combine_video_segments progress
ci / build (push) Failing after 1s
Details
ci / build (push) Failing after 1s
Details
This commit is contained in:
parent
a5e4fee3a3
commit
614bf16cf8
45
Tiltfile
45
Tiltfile
|
@ -202,7 +202,6 @@ docker_build(
|
|||
'./pnpm-workspace.yaml',
|
||||
'./packages/types',
|
||||
'./packages/utils',
|
||||
'./packages/image',
|
||||
'./services/scout',
|
||||
],
|
||||
dockerfile='./dockerfiles/scout.dockerfile',
|
||||
|
@ -244,12 +243,12 @@ cmd_button('postgres:refresh',
|
|||
text='Refresh schema cache'
|
||||
)
|
||||
|
||||
cmd_button('capture-api:create',
|
||||
argv=['http', '--ignore-stdin', 'POST', 'http://localhost:5003/api/record', "url='https://twitch.tv/ironmouse'", "channel='ironmouse'"],
|
||||
resource='capture-api',
|
||||
icon_name='send',
|
||||
text='Start Recording'
|
||||
)
|
||||
# cmd_button('capture-api:create',
|
||||
# argv=['http', '--ignore-stdin', 'POST', 'http://localhost:5003/api/record', "url='https://twitch.tv/ironmouse'", "channel='ironmouse'"],
|
||||
# resource='capture-api',
|
||||
# icon_name='send',
|
||||
# text='Start Recording'
|
||||
# )
|
||||
|
||||
cmd_button('postgres:migrate',
|
||||
argv=['./scripts/postgres-migrations.sh'],
|
||||
|
@ -322,7 +321,6 @@ docker_build(
|
|||
'./package.json',
|
||||
'./pnpm-lock.yaml',
|
||||
'./pnpm-workspace.yaml',
|
||||
'./packages/image',
|
||||
'./services/mailbox',
|
||||
'./packages/types',
|
||||
'./packages/utils',
|
||||
|
@ -339,25 +337,6 @@ docker_build(
|
|||
|
||||
|
||||
|
||||
# docker_build(
|
||||
# 'fp/meal',
|
||||
# '.',
|
||||
# dockerfile='dockerfiles/meal.dockerfile',
|
||||
# target='meal',
|
||||
# only=[
|
||||
# './.npmrc',
|
||||
# './package.json',
|
||||
# './pnpm-lock.yaml',
|
||||
# './pnpm-workspace.yaml',
|
||||
# './packages/meal',
|
||||
# './packages/taco',
|
||||
# './packages/types',
|
||||
# ],
|
||||
# live_update=[
|
||||
# sync('./packages/meal', '/app'),
|
||||
# # run('cd /app && pnpm i', trigger=['./packages/meal/package.json', './packages/meal/pnpm-lock.yaml']),
|
||||
# ],
|
||||
# )
|
||||
|
||||
docker_build(
|
||||
'fp/capture',
|
||||
|
@ -526,12 +505,12 @@ k8s_resource(
|
|||
labels=['backend'],
|
||||
resource_deps=['postgrest'],
|
||||
)
|
||||
k8s_resource(
|
||||
workload='capture-api',
|
||||
port_forwards=['5003'],
|
||||
labels=['backend'],
|
||||
resource_deps=['postgrest', 'postgresql-primary'],
|
||||
)
|
||||
# k8s_resource(
|
||||
# workload='capture-api',
|
||||
# port_forwards=['5003'],
|
||||
# labels=['backend'],
|
||||
# resource_deps=['postgrest', 'postgresql-primary'],
|
||||
# )
|
||||
k8s_resource(
|
||||
workload='capture-worker',
|
||||
labels=['backend'],
|
||||
|
|
|
@ -2,21 +2,21 @@
|
|||
|
||||
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: capture-api
|
||||
namespace: futureporn
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app.kubernetes.io/name: capture
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.capture.api.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
# ---
|
||||
# apiVersion: v1
|
||||
# kind: Service
|
||||
# metadata:
|
||||
# name: capture-api
|
||||
# namespace: futureporn
|
||||
# spec:
|
||||
# type: ClusterIP
|
||||
# selector:
|
||||
# app.kubernetes.io/name: capture
|
||||
# ports:
|
||||
# - name: http
|
||||
# port: {{ .Values.capture.api.port }}
|
||||
# targetPort: http
|
||||
# protocol: TCP
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
|
@ -86,47 +86,47 @@ spec:
|
|||
restartPolicy: Always
|
||||
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: capture-api
|
||||
namespace: futureporn
|
||||
labels:
|
||||
app.kubernetes.io/name: capture
|
||||
spec:
|
||||
replicas: {{ .Values.capture.api.replicas }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app: capture-api
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: capture-api
|
||||
spec:
|
||||
containers:
|
||||
- name: capture
|
||||
image: "{{ .Values.capture.imageName }}"
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.capture.api.port }}
|
||||
env:
|
||||
- name: FUNCTION
|
||||
value: api
|
||||
- name: HTTP_PROXY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: capture
|
||||
key: httpProxy
|
||||
- name: WORKER_CONNECTION_STRING
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: capture
|
||||
key: workerConnectionString
|
||||
- name: PORT
|
||||
value: "{{ .Values.capture.api.port }}"
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
restartPolicy: Always
|
||||
# ---
|
||||
# apiVersion: apps/v1
|
||||
# kind: Deployment
|
||||
# metadata:
|
||||
# name: capture-api
|
||||
# namespace: futureporn
|
||||
# labels:
|
||||
# app.kubernetes.io/name: capture
|
||||
# spec:
|
||||
# replicas: {{ .Values.capture.api.replicas }}
|
||||
# selector:
|
||||
# matchLabels:
|
||||
# app: capture-api
|
||||
# template:
|
||||
# metadata:
|
||||
# labels:
|
||||
# app: capture-api
|
||||
# spec:
|
||||
# containers:
|
||||
# - name: capture
|
||||
# image: "{{ .Values.capture.imageName }}"
|
||||
# ports:
|
||||
# - name: http
|
||||
# containerPort: {{ .Values.capture.api.port }}
|
||||
# env:
|
||||
# - name: FUNCTION
|
||||
# value: api
|
||||
# - name: HTTP_PROXY
|
||||
# valueFrom:
|
||||
# secretKeyRef:
|
||||
# name: capture
|
||||
# key: httpProxy
|
||||
# - name: WORKER_CONNECTION_STRING
|
||||
# valueFrom:
|
||||
# secretKeyRef:
|
||||
# name: capture
|
||||
# key: workerConnectionString
|
||||
# - name: PORT
|
||||
# value: "{{ .Values.capture.api.port }}"
|
||||
# resources:
|
||||
# limits:
|
||||
# cpu: 100m
|
||||
# memory: 256Mi
|
||||
# restartPolicy: Always
|
||||
|
|
|
@ -37,7 +37,9 @@ spec:
|
|||
value: "{{ .Values.s3.endpoint }}"
|
||||
- name: S3_REGION
|
||||
value: "{{ .Values.s3.region }}"
|
||||
- name: S3_BUCKET
|
||||
- name: S3_MAIN_BUCKET
|
||||
value: "{{ .Values.s3.buckets.main }}"
|
||||
- name: S3_USC_BUCKET
|
||||
value: "{{ .Values.s3.buckets.usc }}"
|
||||
- name: S3_ACCESS_KEY_ID
|
||||
valueFrom:
|
||||
|
|
|
@ -19,9 +19,8 @@ RUN mkdir -p /app/services/factory && mkdir -p /prod/factory
|
|||
|
||||
## Copy manfiests, lockfiles, and configs into docker context
|
||||
COPY package.json pnpm-lock.yaml .npmrc .
|
||||
# COPY ./packages/image/pnpm-lock.yaml ./packages/image/package.json ./packages/image/
|
||||
# COPY ./packages/storage/pnpm-lock.yaml ./packages/storage/package.json ./packages/storage/
|
||||
# COPY ./packages/utils/pnpm-lock.yaml ./packages/utils/package.json ./packages/utils/
|
||||
COPY ./packages/utils/pnpm-lock.yaml ./packages/utils/package.json ./packages/utils/
|
||||
COPY ./packages/storage/pnpm-lock.yaml ./packages/storage/package.json ./packages/storage/
|
||||
COPY ./packages/types/pnpm-lock.yaml ./packages/types/package.json ./packages/types/
|
||||
COPY ./services/factory/pnpm-lock.yaml ./services/factory/package.json ./services/factory/
|
||||
|
||||
|
@ -31,9 +30,10 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm fetch
|
|||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install -g node-gyp --prefer-offline
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --recursive --frozen-lockfile --prefer-offline
|
||||
## Copy package code into docker context
|
||||
# COPY ./packages/image/ ./packages/image/
|
||||
# COPY ./packages/storage/ ./packages/storage/
|
||||
# COPY ./packages/utils/ ./packages/utils/
|
||||
COPY ./packages/utils/ ./packages/utils/
|
||||
RUN ls -la /app/packages/utils/node_modules/prevvy/
|
||||
RUn cat ./packages/utils/package.json
|
||||
COPY ./packages/storage/ ./packages/storage/
|
||||
COPY ./packages/types/ ./packages/types/
|
||||
COPY ./services/factory/ ./services/factory/
|
||||
# we are grabbing the mp4 files from capture so we can run tests with them
|
||||
|
@ -42,10 +42,6 @@ COPY ./services/capture/src/fixtures ./services/capture/src/fixtures
|
|||
|
||||
FROM install AS build
|
||||
## Transpile TS into JS
|
||||
## we have to build @futureporn/image first because other packages depend on it's built js files
|
||||
## next we build everything else
|
||||
# RUN pnpm --filter=@futureporn/image build
|
||||
# RUN pnpm --filter=!@futureporn/image -r build
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm -r build
|
||||
|
||||
## Copy all production code into one place
|
||||
|
|
|
@ -26,7 +26,6 @@ RUN mkdir -p /app/services/mailbox && mkdir -p /prod/mailbox
|
|||
|
||||
## Copy manfiests, lockfiles, and configs into docker context
|
||||
COPY package.json pnpm-lock.yaml .npmrc .
|
||||
COPY ./packages/image/pnpm-lock.yaml ./packages/image/package.json ./packages/image/
|
||||
COPY ./packages/storage/pnpm-lock.yaml ./packages/storage/package.json ./packages/storage/
|
||||
COPY ./packages/types/pnpm-lock.yaml ./packages/types/package.json ./packages/types/
|
||||
COPY ./packages/utils/pnpm-lock.yaml ./packages/utils/package.json ./packages/utils/
|
||||
|
@ -37,17 +36,13 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm fetch
|
|||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --recursive --frozen-lockfile --prefer-offline
|
||||
|
||||
## Copy package code into docker context
|
||||
COPY ./packages/image/ ./packages/image/
|
||||
COPY ./packages/storage/ ./packages/storage/
|
||||
COPY ./packages/types/ ./packages/types/
|
||||
COPY ./packages/utils/ ./packages/utils/
|
||||
COPY ./services/mailbox/ ./services/mailbox/
|
||||
|
||||
## Transpile TS into JS
|
||||
## we have to build @futureporn/image first because other packages depend on it's built js files
|
||||
## next we build everything else
|
||||
RUN pnpm --filter=@futureporn/mailbox build
|
||||
# RUN pnpm --filter=!@futureporn/image -r build
|
||||
# RUN pnpm -r build
|
||||
|
||||
## Copy all production code into one place
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
## meal is an example package showing how to include dependency workspace packages into the docker build
|
||||
|
||||
FROM node:20.15 AS base
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
WORKDIR /app
|
||||
RUN corepack enable && corepack prepare pnpm@9.6.0 --activate
|
||||
|
||||
FROM base AS build
|
||||
# ENV NODE_ENV=development
|
||||
# RUN mkdir -p /app/packages/meal && mkdir /app/packages/taco && mkdir -p /prod/meal
|
||||
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc .
|
||||
COPY ./packages/meal/pnpm-lock.yaml ./packages/meal/package.json ./packages/meal/
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm fetch
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile --offline
|
||||
COPY ./packages/meal/ ./packages/meal/
|
||||
RUN echo "@@@@@@@@@@@@@@@@@@@@ show me the meat!"
|
||||
RUN ls -lash ./
|
||||
RUN ls -lash ./packages/meal
|
||||
RUN pnpm -r build
|
||||
RUN pnpm deploy --filter=meal --prod /prod/meal
|
||||
|
||||
FROM base AS meal
|
||||
WORKDIR /app
|
||||
ENV NODE_ENV=production
|
||||
COPY --from=build /prod/meal .
|
||||
RUN ls -la .
|
||||
ENTRYPOINT ["pnpm", "start"]
|
||||
|
|
@ -25,7 +25,6 @@ RUN pnpm fetch
|
|||
COPY ./services/next ./services/next
|
||||
COPY ./packages/types ./packages/types
|
||||
# COPY ./packages/strapi ./packages/strapi
|
||||
# COPY ./packages/image ./packages/image
|
||||
# COPY ./packages/utils ./packages/utils
|
||||
|
||||
RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store pnpm install --recursive --frozen-lockfile --prefer-offline
|
||||
|
|
|
@ -21,7 +21,6 @@ FROM base AS install
|
|||
COPY pnpm-lock.yaml .npmrc package.json .
|
||||
COPY ./services/scout/ ./services/scout/
|
||||
COPY ./packages/types/ ./packages/types/
|
||||
COPY ./packages/image/ ./packages/image/
|
||||
COPY ./packages/utils/ ./packages/utils/
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm fetch
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --recursive --frozen-lockfile --prefer-offline
|
||||
|
|
|
@ -29,7 +29,6 @@ RUN mkdir -p /app/packages/worker && mkdir -p /prod/worker
|
|||
## Copy manfiests, lockfiles, and configs into docker context
|
||||
COPY package.json pnpm-lock.yaml .npmrc .
|
||||
RUN corepack enable && corepack prepare pnpm@9.6.0 --activate
|
||||
# COPY ./packages/image/pnpm-lock.yaml ./packages/image/package.json ./packages/image/
|
||||
# COPY ./packages/storage/pnpm-lock.yaml ./packages/storage/package.json ./packages/storage/
|
||||
# COPY ./packages/types/pnpm-lock.yaml ./packages/types/package.json ./packages/types/
|
||||
# COPY ./packages/utils/pnpm-lock.yaml ./packages/utils/package.json ./packages/utils/
|
||||
|
@ -42,17 +41,12 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install -g node-gyp --pre
|
|||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --recursive --frozen-lockfile --prefer-offline
|
||||
|
||||
## Copy package code into docker context
|
||||
# COPY ./packages/image/ ./packages/image/
|
||||
# COPY ./packages/storage/ ./packages/storage/
|
||||
# COPY ./packages/types/ ./packages/types/
|
||||
# COPY ./packages/utils/ ./packages/utils/
|
||||
COPY ./packages/worker/ ./packages/worker/
|
||||
|
||||
## Transpile TS into JS
|
||||
## we have to build @futureporn/image first because other packages depend on it's built js files
|
||||
## next we build everything else
|
||||
# RUN pnpm --filter=@futureporn/image build
|
||||
# RUN pnpm --filter=!@futureporn/image -r build
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm -r build
|
||||
|
||||
## Copy all production code into one place
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/mocharc.json",
|
||||
"extensions": ["ts"],
|
||||
"spec": "./src/**/*.spec.ts",
|
||||
"require": "tsx"
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"name": "@futureporn/image",
|
||||
"type": "module",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"scripts": {
|
||||
"test": "mocha",
|
||||
"clean": "rm -rf dist",
|
||||
"superclean": "rm -rf node_modules && rm -rf pnpm-lock.yaml && rm -rf dist"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "Unlicense",
|
||||
"dependencies": {
|
||||
"@futureporn/utils": "workspace:*",
|
||||
"@types/chai": "^4.3.16",
|
||||
"@types/mocha": "^10.0.7",
|
||||
"prevvy": "^7.0.1",
|
||||
"sharp": "^0.33.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^5.1.1",
|
||||
"mocha": "^10.6.0",
|
||||
"tsx": "^4.17.0"
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,34 +0,0 @@
|
|||
|
||||
import { getProminentColor, rgbToHex, getStoryboard } from './index.js'
|
||||
import { expect } from 'chai'
|
||||
import { describe } from 'mocha'
|
||||
import path from 'node:path'
|
||||
|
||||
|
||||
describe('image', function () {
|
||||
describe('getProminentColor', function () {
|
||||
it('should get a {String} hex code color', async function () {
|
||||
const color = await getProminentColor(path.join(import.meta.dirname, './fixtures/sample.webp'))
|
||||
expect(color).to.equal('#0878a8')
|
||||
})
|
||||
})
|
||||
describe('rgbToHex', function () {
|
||||
it('should convert color to hex {String} hexidecimal code', function () {
|
||||
const mulberry = [255, 87, 51] as const
|
||||
const screaminGreen = [77, 255, 106] as const
|
||||
const amaranth = [227, 64, 81] as const
|
||||
expect(rgbToHex(...mulberry)).to.equal('#ff5733')
|
||||
expect(rgbToHex(...screaminGreen)).to.equal('#4dff6a')
|
||||
expect(rgbToHex(...amaranth)).to.equal('#e34051')
|
||||
})
|
||||
})
|
||||
describe('getStoryboard', function () {
|
||||
this.timeout(1000*60*15)
|
||||
it('should accept a URL and return a path to image on disk', async function () {
|
||||
// const url = 'https://futureporn-b2.b-cdn.net/projektmelody-chaturbate-2024-06-25.mp4'
|
||||
const url = 'https://futureporn-b2.b-cdn.net/projektmelody-chaturbate-2024-08-31.mp4'
|
||||
const imagePath = await getStoryboard(url)
|
||||
expect(imagePath).to.match(/\.png/)
|
||||
})
|
||||
})
|
||||
})
|
|
@ -1,32 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"allowImportingTsExtensions": true,
|
||||
// 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"
|
||||
]
|
||||
},
|
||||
// Include the necessary files for your project
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"src/**/*.spec.ts"
|
||||
]
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
# @futureporn/meal
|
||||
|
||||
A test package to better understand Internal TypeScript Packages [[1](https://github.com/0x80/isolate-package?tab=readme-ov-file#the-internal-packages-strategy)] [[2](https://turbo.build/blog/you-might-not-need-typescript-project-references)] [[3](https://www.typescriptlang.org/docs/handbook/project-references.html)]
|
||||
|
||||
The TL;DR: The consuming application of an internal package must transpile and typecheck it.
|
||||
|
||||
In this example, @futureporn/meal consumes @futureporn/taco. A build step happens only in @futureporn/meal.
|
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"name": "@futureporn/meal",
|
||||
"type": "module",
|
||||
"version": "1.0.1",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"test": "echo \"Warn: no test specified\" && exit 0",
|
||||
"start": "node dist/index.js",
|
||||
"build": "tsc --build",
|
||||
"clean": "rm -rf dist",
|
||||
"superclean": "rm -rf node_modules && rm -rf pnpm-lock.yaml && rm -rf dist",
|
||||
"dev": "tsup ./src/index.ts --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@futureporn/taco": "workspace:*",
|
||||
"@futureporn/types": "workspace:*"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "@CJ_Clippy",
|
||||
"license": "Unlicense",
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.14.9",
|
||||
"tsup": "^8.1.2",
|
||||
"typescript": "^5.5.3"
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,10 +0,0 @@
|
|||
import { type Taco, taco } from '@futureporn/taco'
|
||||
|
||||
function main() {
|
||||
console.log(`Oh boy, it's time for another delicious ${taco()}!!`)
|
||||
setTimeout(() => {
|
||||
return main()
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
main()
|
|
@ -1,31 +0,0 @@
|
|||
{
|
||||
"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"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"tsub.config.ts"
|
||||
]
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
import { defineConfig } from "tsup";
|
||||
import { exec } from 'child_process';
|
||||
|
||||
export default defineConfig({
|
||||
entry: ["src/index.ts"],
|
||||
format: ["esm"],
|
||||
target: "node20",
|
||||
clean: true,
|
||||
sourcemap: true,
|
||||
/**
|
||||
* The common package is using the internal packages approach, so it needs to
|
||||
* be transpiled / bundled together with the deployed code.
|
||||
*/
|
||||
noExternal: ["@futureporn/taco"],
|
||||
/**
|
||||
* We do not use tsup for generating d.ts files because it can not generate type
|
||||
* the definition maps required for go-to-definition to work in our IDE. We
|
||||
* use tsc for that.
|
||||
*/
|
||||
onSuccess: async () => {
|
||||
exec('tsc --emitDeclarationOnly');
|
||||
},
|
||||
});
|
|
@ -1 +0,0 @@
|
|||
dist
|
|
@ -1 +0,0 @@
|
|||
dist
|
|
@ -1,5 +0,0 @@
|
|||
# temporal-workflows
|
||||
|
||||
based on https://github.com/temporalio/samples-typescript/tree/main/monorepo-folders
|
||||
|
||||
Futureporn has a lot of long-running tasks that need to run in the background. The tasks are defined here, and any other package can invoke them via a Temporal worker.
|
|
@ -1,33 +0,0 @@
|
|||
{
|
||||
"name": "@futureporn/temporal-workflows",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"exports": {
|
||||
"./workflows": "./src/workflows.ts",
|
||||
"./activities": "./src/activities.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"superclean": "rm -rf node_modules && rm -rf pnpm-lock.yaml && rm -rf dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/qs": "^6.9.15",
|
||||
"date-fns": "^3.6.0",
|
||||
"qs": "^6.12.3",
|
||||
"@futureporn/image": "workspace:*",
|
||||
"@futureporn/scout": "workspace:*",
|
||||
"@futureporn/storage": "workspace:*",
|
||||
"@futureporn/types": "workspace:*",
|
||||
"@futureporn/utils": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||
"@typescript-eslint/parser": "^5.62.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-prettier": "^8.10.0",
|
||||
"eslint-plugin-deprecation": "^1.5.0",
|
||||
"nodemon": "^3.1.4",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.5.3"
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,334 +0,0 @@
|
|||
|
||||
import { type NotificationData } from '@futureporn/types'
|
||||
import { type Helpers } from 'graphile-worker'
|
||||
import {
|
||||
type IStreamResponse,
|
||||
type IStreamsResponse,
|
||||
type IPlatformNotificationResponse,
|
||||
type IVtubersResponse,
|
||||
type IVtuberResponse,
|
||||
type IVtuber,
|
||||
} from '@futureporn/types'
|
||||
import { subMinutes, addMinutes } from 'date-fns'
|
||||
import qs from 'qs'
|
||||
import { getProminentColor } from '@futureporn/image'
|
||||
import { getImage } from '@futureporn/scout/vtuber.js'
|
||||
import { fpSlugify } from '@futureporn/utils'
|
||||
import { uploadFile } from '@futureporn/storage/s3.js'
|
||||
|
||||
export async function upsertStream({
|
||||
date,
|
||||
vtuberId,
|
||||
platform,
|
||||
pNotifId
|
||||
}: {
|
||||
date: string,
|
||||
vtuberId: number,
|
||||
platform: string,
|
||||
pNotifId: number
|
||||
}, helpers: Helpers): Promise<number> {
|
||||
|
||||
if (!date) throw new Error(`upsertStream requires date in the arg object, but it was undefined`);
|
||||
if (!vtuberId) throw new Error(`upsertStream requires vtuberId in the arg object, but it was undefined`);
|
||||
if (!platform) throw new Error(`upsertStream requires platform in the arg object, but it was undefined`);
|
||||
if (!pNotifId) throw new Error(`upsertStream requires pNotifId in the arg object, but it was undefined`);
|
||||
|
||||
let streamId
|
||||
// # Step 3.
|
||||
// Finally we find or create the stream record
|
||||
// The stream may already be in the db (the streamer is multi-platform streaming), so we look for that record.
|
||||
// This gets a bit tricky. How do we determine one stream from another?
|
||||
// For now, the rule is 30 minutes of separation.
|
||||
// Anything <=30m is interpreted as the same stream. Anything >30m is interpreted as a different stream.
|
||||
// If the stream is not in the db, we create the stream record
|
||||
const dateSinceRange = subMinutes(new Date(date), 30)
|
||||
const dateUntilRange = addMinutes(new Date(date), 30)
|
||||
helpers.logger.info(`Find a stream within + or - 30 mins of the notif date=${new Date(date).toISOString()}. dateSinceRange=${dateSinceRange.toISOString()}, dateUntilRange=${dateUntilRange.toISOString()}`)
|
||||
const findStreamQueryString = qs.stringify({
|
||||
populate: 'platform-notifications',
|
||||
filters: {
|
||||
date: {
|
||||
$gte: dateSinceRange,
|
||||
$lte: dateUntilRange
|
||||
},
|
||||
vtuber: {
|
||||
id: {
|
||||
'$eq': vtuberId
|
||||
}
|
||||
}
|
||||
}
|
||||
}, { encode: false })
|
||||
|
||||
helpers.logger.info('>> findStream')
|
||||
const findStreamRes = await fetch(`${process.env.STRAPI_URL}/api/streams?${findStreamQueryString}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'authorization': `Bearer ${process.env.SCOUT_STRAPI_API_KEY}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
const findStreamData = await findStreamRes.json() as IStreamsResponse
|
||||
if (findStreamData?.data && findStreamData.data.length > 0) {
|
||||
helpers.logger.info('>> we found a findStreamData json. (there is an existing stream for this e-mail/notification)')
|
||||
helpers.logger.info(JSON.stringify(findStreamData, null, 2))
|
||||
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.
|
||||
// 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
|
||||
let isFanslyStream = false
|
||||
let isChaturbateStream = false
|
||||
if (stream.attributes.platformNotifications) {
|
||||
for (const pn of stream.attributes.platformNotifications) {
|
||||
if (pn.attributes.platform === 'fansly') {
|
||||
isFanslyStream = true
|
||||
} else if (pn.attributes.platform === 'chaturbate') {
|
||||
isChaturbateStream = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
helpers.logger.info(`>>> updating stream ${streamId}. isFanslyStream=${isFanslyStream}, isChaturbateStream=${isChaturbateStream}`)
|
||||
const updateStreamRes = await fetch(`${process.env.STRAPI_URL}/api/streams/${streamId}`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'authorization': `Bearer ${process.env.SCOUT_STRAPI_API_KEY}`,
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
data: {
|
||||
isFanslyStream: isFanslyStream,
|
||||
isChaturbateStream: isChaturbateStream,
|
||||
platformNotifications: [
|
||||
pNotifId
|
||||
]
|
||||
}
|
||||
})
|
||||
})
|
||||
const updateStreamJson = await updateStreamRes.json() as IStreamResponse
|
||||
if (updateStreamJson?.error) throw new Error(JSON.stringify(updateStreamJson, null, 2));
|
||||
helpers.logger.info(`>> assuming a successful update to the stream record. response as follows.`)
|
||||
helpers.logger.info(JSON.stringify(updateStreamJson, null, 2))
|
||||
}
|
||||
|
||||
if (!streamId) {
|
||||
helpers.logger.info('>> did not find a streamId, so we go ahead and create a stream record in the db.')
|
||||
const createStreamPayload = {
|
||||
data: {
|
||||
isFanslyStream: (platform === 'fansly') ? true : false,
|
||||
isChaturbateStream: (platform === 'chaturbate') ? true : false,
|
||||
archiveStatus: 'missing',
|
||||
date: date,
|
||||
date2: date,
|
||||
date_str: date,
|
||||
vtuber: vtuberId,
|
||||
platformNotifications: [
|
||||
pNotifId
|
||||
]
|
||||
}
|
||||
}
|
||||
helpers.logger.debug('>> createStreamPayload as follows')
|
||||
helpers.logger.debug(JSON.stringify(createStreamPayload, null, 2))
|
||||
const createStreamRes = await fetch(`${process.env.STRAPI_URL}/api/streams`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'authorization': `Bearer ${process.env.SCOUT_STRAPI_API_KEY}`,
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(createStreamPayload)
|
||||
})
|
||||
const createStreamJson = await createStreamRes.json() as IStreamResponse
|
||||
helpers.logger.debug('>> we got the createStreamJson')
|
||||
helpers.logger.debug(JSON.stringify(createStreamJson, null, 2))
|
||||
if (createStreamJson.error) {
|
||||
console.error(JSON.stringify(createStreamJson.error, null, 2))
|
||||
throw new Error('Failed to create stream in DB due to an error. (see above)')
|
||||
}
|
||||
streamId = createStreamJson.data.id
|
||||
}
|
||||
|
||||
if (!streamId) throw new Error('failed to get streamId')
|
||||
return streamId
|
||||
}
|
||||
|
||||
|
||||
export async function upsertPlatformNotification({ source, date, platform, vtuberId }: { source: string, date: string, platform: string, vtuberId: number }, helpers: Helpers): Promise<number> {
|
||||
helpers.logger.info('hello from upsertPlatformNotification', { source, date, platform, vtuberId });
|
||||
|
||||
if (!source) throw new Error(`upsertPlatformNotification requires source arg, but it was undefined`);
|
||||
if (!date) throw new Error(`upsertPlatformNotification requires date arg, but it was undefined`);
|
||||
if (!platform) throw new Error(`upsertPlatformNotification requires platform arg, but it was undefined`);
|
||||
if (!vtuberId) throw new Error(`upsertPlatformNotification requires vtuberId arg, but it was undefined`);
|
||||
|
||||
let pNotifId
|
||||
// # Step 2.
|
||||
// Next we create the platform-notification record.
|
||||
// This probably doesn't already exist, so we don't check for a pre-existing platform-notification.
|
||||
const pNotifPayload = {
|
||||
data: {
|
||||
source: source,
|
||||
date: date,
|
||||
date2: date,
|
||||
platform: platform,
|
||||
vtuber: vtuberId,
|
||||
}
|
||||
}
|
||||
helpers.logger.debug('pNotifPayload as follows')
|
||||
helpers.logger.debug(JSON.stringify(pNotifPayload, null, 2))
|
||||
|
||||
const pNotifCreateRes = await fetch(`${process.env.STRAPI_URL}/api/platform-notifications`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'authorization': `Bearer ${process.env.SCOUT_STRAPI_API_KEY}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(pNotifPayload)
|
||||
})
|
||||
const pNotifData = await pNotifCreateRes.json() as IPlatformNotificationResponse
|
||||
if (pNotifData.error) {
|
||||
helpers.logger.error('>> we failed to create platform-notification, there was an error in the response')
|
||||
helpers.logger.error(JSON.stringify(pNotifData.error, null, 2))
|
||||
throw new Error(pNotifData.error)
|
||||
}
|
||||
helpers.logger.debug(`>> pNotifData (json response) is as follows`)
|
||||
helpers.logger.debug(JSON.stringify(pNotifData, null, 2))
|
||||
if (!pNotifData.data?.id) throw new Error('failed to created pNotifData! The response was missing an id');
|
||||
|
||||
pNotifId = pNotifData.data.id
|
||||
if (!pNotifId) throw new Error('failed to get Platform Notification ID');
|
||||
return pNotifId
|
||||
|
||||
}
|
||||
export async function upsertVtuber({ platform, userId, url, channel }: { platform: string, userId: string | null, url: string, channel: string }, helpers: Helpers): Promise<number> {
|
||||
|
||||
let vtuberId
|
||||
helpers.logger.debug('>> # Step 1, upsertVtuber')
|
||||
// # Step 1.
|
||||
// First we find or create the vtuber
|
||||
// The vtuber may already be in the db, so we look for that record. All we need is the Vtuber ID.
|
||||
// If the vtuber is not in the db, we create the vtuber record.
|
||||
|
||||
// GET /api/:pluralApiId?filters[field][operator]=value
|
||||
const findVtubersFilters = (() => {
|
||||
if (platform === 'chaturbate') {
|
||||
return { chaturbate: { $eq: url } }
|
||||
} else if (platform === 'fansly') {
|
||||
if (!userId) throw new Error('Fansly userId was undefined, but it is required.')
|
||||
return { fanslyId: { $eq: userId } }
|
||||
}
|
||||
})()
|
||||
helpers.logger.debug('>>>>> the following is findVtubersFilters.')
|
||||
helpers.logger.debug(JSON.stringify(findVtubersFilters, null, 2))
|
||||
|
||||
const findVtubersQueryString = qs.stringify({
|
||||
filters: findVtubersFilters
|
||||
}, { encode: false })
|
||||
helpers.logger.debug(`>>>>> platform=${platform}, url=${url}, userId=${userId}`)
|
||||
|
||||
helpers.logger.debug('>> findVtuber')
|
||||
const findVtuberRes = await fetch(`${process.env.STRAPI_URL}/api/vtubers?${findVtubersQueryString}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
})
|
||||
const findVtuberJson = await findVtuberRes.json() as IVtubersResponse
|
||||
helpers.logger.debug('>> here is the vtuber json')
|
||||
helpers.logger.debug(JSON.stringify(findVtuberJson, null, 2))
|
||||
if (findVtuberJson?.data && findVtuberJson.data.length > 0) {
|
||||
helpers.logger.debug('>> a vtuber was FOUND')
|
||||
if (findVtuberJson.data.length > 1) throw new Error('There were more than one vtuber matches in the response. There must only be one.');
|
||||
const vtuber = findVtuberJson.data[0]
|
||||
if (!vtuber) throw new Error('vtuber did not have an id. vtuber must have an id.')
|
||||
helpers.logger.debug('here is the findVtuberJson (as follows)')
|
||||
helpers.logger.debug(JSON.stringify(findVtuberJson, null, 2))
|
||||
helpers.logger.debug(`the matching vtuber has ID=${vtuber.id} (${vtuber.attributes.displayName})`)
|
||||
}
|
||||
|
||||
if (!vtuberId) {
|
||||
helpers.logger.info('>> vtuberId was not found so we create')
|
||||
|
||||
/**
|
||||
* We are creating a vtuber record.
|
||||
* We need a few things.
|
||||
* * image URL
|
||||
* * themeColor
|
||||
*
|
||||
* To get an image, we have to do a few things.
|
||||
* * [x] download image from platform
|
||||
* * [x] get themeColor from image
|
||||
* * [x] upload image to b2
|
||||
* * [x] get B2 cdn link to image
|
||||
*
|
||||
* To get themeColor, we need the image locally where we can then run
|
||||
*/
|
||||
|
||||
// download image from platform
|
||||
// vtuber.getImage expects a vtuber object, which we don't have yet, so we create a dummy one
|
||||
const dummyVtuber: IVtuber = {
|
||||
id: 69,
|
||||
attributes: {
|
||||
slug: fpSlugify(channel),
|
||||
displayName: 'example',
|
||||
vods: [],
|
||||
description1: ' ',
|
||||
image: ' ',
|
||||
themeColor: ' ',
|
||||
fanslyId: (platform === 'fansly') ? (userId ? userId : undefined) : undefined
|
||||
}
|
||||
}
|
||||
const imageFile = await getImage(dummyVtuber)
|
||||
|
||||
// get themeColor from image
|
||||
const themeColor = await getProminentColor(imageFile)
|
||||
|
||||
// upload image to b2
|
||||
const b2FileData = await uploadFile(imageFile)
|
||||
|
||||
// get b2 cdn link to image
|
||||
const imageCdnLink = `${process.env.CDN_BUCKET_URL}/${b2FileData.Key}`
|
||||
|
||||
helpers.logger.info(`>>> createVtuberRes here we go 3-2-1, POST!`)
|
||||
const createVtuberRes = await fetch(`${process.env.STRAPI_URL}/api/vtubers`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'authorization': `Bearer ${process.env.SCOUT_STRAPI_API_KEY}`,
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
data: {
|
||||
displayName: channel,
|
||||
fansly: (platform === 'fansly') ? url : null,
|
||||
fanslyId: (platform === 'fansly') ? userId : null,
|
||||
chaturbate: (platform === 'chaturbate') ? url : null,
|
||||
slug: fpSlugify(channel),
|
||||
description1: ' ',
|
||||
image: imageCdnLink,
|
||||
themeColor: themeColor || '#dde1ec'
|
||||
}
|
||||
})
|
||||
})
|
||||
const createVtuberJson = await createVtuberRes.json() as IVtuberResponse
|
||||
helpers.logger.info('>> createVtuberJson as follows')
|
||||
helpers.logger.info(JSON.stringify(createVtuberJson, null, 2))
|
||||
if (createVtuberJson.data) {
|
||||
vtuberId = createVtuberJson.data.id
|
||||
helpers.logger.info(`>>> vtuber created with id=${vtuberId}`)
|
||||
}
|
||||
}
|
||||
if (!vtuberId) throw new Error(`upsertVtuber failed to produce a vtuberId! This should not happen under normal circumstances.`);
|
||||
return vtuberId
|
||||
}
|
||||
|
||||
export default async function (payload: NotificationData, helpers: Helpers) {
|
||||
const source = 'email'
|
||||
const { url, platform, channel, displayName, date, userId, avatar } = payload
|
||||
helpers.logger.info(`process_notif_email task execution has begun with date=${date}, channel=${channel}, platform=${platform}, url=${url}, displayName=${displayName}, avatar=${avatar}`);
|
||||
const vtuberId = await upsertVtuber({channel, platform, url, userId }, helpers);
|
||||
const pNotifId = await upsertPlatformNotification({date, platform, source, vtuberId}, helpers);
|
||||
const streamId = await upsertStream({date, platform, pNotifId, vtuberId}, helpers);
|
||||
return `vtuberId: ${vtuberId} | pNotifId: ${pNotifId} | streamId: ${streamId}`;
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
export * from './workflowA/activities/activitiesA.js'
|
||||
export * from './workflowA/activities/activitiesB.js'
|
||||
// export * from './workflowB/activities.js'
|
||||
// export * from './processNotifEmail/activities/upsertPlatformNotification.js'
|
||||
// export * from './processNotifEmail/activities/upsertStream.js'
|
||||
// export * from './processNotifEmail/activities/upsertVtuber.js'
|
|
@ -1,60 +0,0 @@
|
|||
|
||||
import { log } from '@temporalio/activity';
|
||||
import { type IPlatformNotificationResponse, type IVtuberResponse, type IStreamResponse } from '@futureporn/types'
|
||||
|
||||
|
||||
if (!process.env.SCOUT_STRAPI_API_KEY) throw new Error('SCOUT_STRAPI_API_KEY is missing from env');
|
||||
if (!process.env.STRAPI_URL) throw new Error('STRAPI_URL is missing from env');
|
||||
if (!process.env.CDN_BUCKET_URL) throw new Error('CDN_BUCKET_URL is missing from env');
|
||||
if (!process.env.SCOUT_NITTER_URL) throw new Error('SCOUT_NITTER_URL is missing from env');
|
||||
if (!process.env.SCOUT_NITTER_ACCESS_KEY) throw new Error('SCOUT_NITTER_ACCESS_KEY is missing from env');
|
||||
|
||||
|
||||
|
||||
export async function upsertPlatformNotification({ source, date, platform, vtuberId }: { source: string, date: string, platform: string, vtuberId: number }): Promise<number> {
|
||||
log.info('hello from upsertPlatformNotification', { source, date, platform, vtuberId });
|
||||
|
||||
if (!source) throw new Error(`upsertPlatformNotification requires source arg, but it was undefined`);
|
||||
if (!date) throw new Error(`upsertPlatformNotification requires date arg, but it was undefined`);
|
||||
if (!platform) throw new Error(`upsertPlatformNotification requires platform arg, but it was undefined`);
|
||||
if (!vtuberId) throw new Error(`upsertPlatformNotification requires vtuberId arg, but it was undefined`);
|
||||
|
||||
let pNotifId
|
||||
// # Step 2.
|
||||
// Next we create the platform-notification record.
|
||||
// This probably doesn't already exist, so we don't check for a pre-existing platform-notification.
|
||||
const pNotifPayload = {
|
||||
data: {
|
||||
source: source,
|
||||
date: date,
|
||||
date2: date,
|
||||
platform: platform,
|
||||
vtuber: vtuberId,
|
||||
}
|
||||
}
|
||||
console.log('pNotifPayload as follows')
|
||||
console.log(pNotifPayload)
|
||||
|
||||
const pNotifCreateRes = await fetch(`${process.env.STRAPI_URL}/api/platform-notifications`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'authorization': `Bearer ${process.env.SCOUT_STRAPI_API_KEY}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(pNotifPayload)
|
||||
})
|
||||
const pNotifData = await pNotifCreateRes.json() as IPlatformNotificationResponse
|
||||
if (pNotifData.error) {
|
||||
console.error('>> we failed to create platform-notification, there was an error in the response')
|
||||
console.error(JSON.stringify(pNotifData.error, null, 2))
|
||||
throw new Error(pNotifData.error)
|
||||
}
|
||||
console.log(`>> pNotifData (json response) is as follows`)
|
||||
console.log(pNotifData)
|
||||
if (!pNotifData.data?.id) throw new Error('failed to created pNotifData! The response was missing an id');
|
||||
|
||||
pNotifId = pNotifData.data.id
|
||||
if (!pNotifId) throw new Error('failed to get Platform Notification ID');
|
||||
return pNotifId
|
||||
|
||||
}
|
|
@ -1,141 +0,0 @@
|
|||
import { type IStreamResponse, type IStreamsResponse } from '@futureporn/types';
|
||||
import { subMinutes, addMinutes } from 'date-fns';
|
||||
import qs from 'qs'
|
||||
|
||||
export async function upsertStream({
|
||||
date,
|
||||
vtuberId,
|
||||
platform,
|
||||
pNotifId
|
||||
}: {
|
||||
date: string,
|
||||
vtuberId: number,
|
||||
platform: string,
|
||||
pNotifId: number
|
||||
}): Promise<number> {
|
||||
|
||||
if (!date) throw new Error(`upsertStream requires date in the arg object, but it was undefined`);
|
||||
if (!vtuberId) throw new Error(`upsertStream requires vtuberId in the arg object, but it was undefined`);
|
||||
if (!platform) throw new Error(`upsertStream requires platform in the arg object, but it was undefined`);
|
||||
if (!pNotifId) throw new Error(`upsertStream requires pNotifId in the arg object, but it was undefined`);
|
||||
|
||||
let streamId
|
||||
// # Step 3.
|
||||
// Finally we find or create the stream record
|
||||
// The stream may already be in the db (the streamer is multi-platform streaming), so we look for that record.
|
||||
// This gets a bit tricky. How do we determine one stream from another?
|
||||
// For now, the rule is 30 minutes of separation.
|
||||
// Anything <=30m is interpreted as the same stream. Anything >30m is interpreted as a different stream.
|
||||
// If the stream is not in the db, we create the stream record
|
||||
const dateSinceRange = subMinutes(new Date(date), 30)
|
||||
const dateUntilRange = addMinutes(new Date(date), 30)
|
||||
console.log(`Find a stream within + or - 30 mins of the notif date=${new Date(date).toISOString()}. dateSinceRange=${dateSinceRange.toISOString()}, dateUntilRange=${dateUntilRange.toISOString()}`)
|
||||
const findStreamQueryString = qs.stringify({
|
||||
populate: 'platform-notifications',
|
||||
filters: {
|
||||
date: {
|
||||
$gte: dateSinceRange,
|
||||
$lte: dateUntilRange
|
||||
},
|
||||
vtuber: {
|
||||
id: {
|
||||
'$eq': vtuberId
|
||||
}
|
||||
}
|
||||
}
|
||||
}, { encode: false })
|
||||
|
||||
console.log('>> findStream')
|
||||
const findStreamRes = await fetch(`${process.env.STRAPI_URL}/api/streams?${findStreamQueryString}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'authorization': `Bearer ${process.env.SCOUT_STRAPI_API_KEY}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
const findStreamData = await findStreamRes.json() as IStreamsResponse
|
||||
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(JSON.stringify(findStreamData, null, 2))
|
||||
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.
|
||||
// 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
|
||||
let isFanslyStream = false
|
||||
let isChaturbateStream = false
|
||||
if (stream.attributes.platformNotifications) {
|
||||
for (const pn of stream.attributes.platformNotifications) {
|
||||
if (pn.attributes.platform === 'fansly') {
|
||||
isFanslyStream = true
|
||||
} else if (pn.attributes.platform === 'chaturbate') {
|
||||
isChaturbateStream = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
console.log(`>>> updating stream ${streamId}. isFanslyStream=${isFanslyStream}, isChaturbateStream=${isChaturbateStream}`)
|
||||
const updateStreamRes = await fetch(`${process.env.STRAPI_URL}/api/streams/${streamId}`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'authorization': `Bearer ${process.env.SCOUT_STRAPI_API_KEY}`,
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
data: {
|
||||
isFanslyStream: isFanslyStream,
|
||||
isChaturbateStream: isChaturbateStream,
|
||||
platformNotifications: [
|
||||
pNotifId
|
||||
]
|
||||
}
|
||||
})
|
||||
})
|
||||
const updateStreamJson = await updateStreamRes.json() as IStreamResponse
|
||||
if (updateStreamJson?.error) throw new Error(JSON.stringify(updateStreamJson, null, 2));
|
||||
console.log(`>> assuming a successful update to the stream record. response as follows.`)
|
||||
console.log(JSON.stringify(updateStreamJson, null, 2))
|
||||
}
|
||||
|
||||
if (!streamId) {
|
||||
console.log('>> did not find a streamId, so we go ahead and create a stream record in the db.')
|
||||
const createStreamPayload = {
|
||||
data: {
|
||||
isFanslyStream: (platform === 'fansly') ? true : false,
|
||||
isChaturbateStream: (platform === 'chaturbate') ? true : false,
|
||||
archiveStatus: 'missing',
|
||||
date: date,
|
||||
date2: date,
|
||||
date_str: date,
|
||||
vtuber: vtuberId,
|
||||
platformNotifications: [
|
||||
pNotifId
|
||||
]
|
||||
}
|
||||
}
|
||||
console.log('>> createStreamPayload as follows')
|
||||
console.log(createStreamPayload)
|
||||
const createStreamRes = await fetch(`${process.env.STRAPI_URL}/api/streams`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'authorization': `Bearer ${process.env.SCOUT_STRAPI_API_KEY}`,
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(createStreamPayload)
|
||||
})
|
||||
const createStreamJson = await createStreamRes.json() as IStreamResponse
|
||||
console.log('>> we got the createStreamJson')
|
||||
console.log(createStreamJson)
|
||||
if (createStreamJson.error) {
|
||||
console.error(JSON.stringify(createStreamJson.error, null, 2))
|
||||
throw new Error('Failed to create stream in DB due to an error. (see above)')
|
||||
}
|
||||
streamId = createStreamJson.data.id
|
||||
}
|
||||
|
||||
if (!streamId) throw new Error('failed to get streamId')
|
||||
return streamId
|
||||
}
|
|
@ -1,130 +0,0 @@
|
|||
import { type IVtubersResponse, type IVtuberResponse, type IVtuber } from '@futureporn/types';
|
||||
import { fpSlugify } from '@futureporn/utils';
|
||||
import qs from 'qs';
|
||||
import { getProminentColor } from '@futureporn/image';
|
||||
import { getImage } from '@futureporn/scout/vtuber.js';
|
||||
import { uploadFile } from '@futureporn/storage/s3.js';
|
||||
|
||||
/**
|
||||
* find or create vtuber in Strapi
|
||||
*/
|
||||
export async function upsertVtuber({ platform, userId, url, channel }: { platform: string, userId: string | null, url: string, channel: string }): Promise<number> {
|
||||
|
||||
let vtuberId
|
||||
console.log('>> # Step 1, upsertVtuber')
|
||||
// # Step 1.
|
||||
// First we find or create the vtuber
|
||||
// The vtuber may already be in the db, so we look for that record. All we need is the Vtuber ID.
|
||||
// If the vtuber is not in the db, we create the vtuber record.
|
||||
|
||||
// GET /api/:pluralApiId?filters[field][operator]=value
|
||||
const findVtubersFilters = (() => {
|
||||
if (platform === 'chaturbate') {
|
||||
return { chaturbate: { $eq: url } }
|
||||
} else if (platform === 'fansly') {
|
||||
if (!userId) throw new Error('Fansly userId was undefined, but it is required.')
|
||||
return { fanslyId: { $eq: userId } }
|
||||
}
|
||||
})()
|
||||
console.log('>>>>> the following is findVtubersFilters.')
|
||||
console.log(findVtubersFilters)
|
||||
|
||||
const findVtubersQueryString = qs.stringify({
|
||||
filters: findVtubersFilters
|
||||
}, { encode: false })
|
||||
console.log(`>>>>> platform=${platform}, url=${url}, userId=${userId}`)
|
||||
|
||||
console.log('>> findVtuber')
|
||||
const findVtuberRes = await fetch(`${process.env.STRAPI_URL}/api/vtubers?${findVtubersQueryString}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
})
|
||||
const findVtuberJson = await findVtuberRes.json() as IVtubersResponse
|
||||
console.log('>> here is the vtuber json')
|
||||
console.log(findVtuberJson)
|
||||
if (findVtuberJson?.data && findVtuberJson.data.length > 0) {
|
||||
console.log('>> a vtuber was FOUND')
|
||||
if (findVtuberJson.data.length > 1) throw new Error('There were more than one vtuber matches in the response. There must only be one.');
|
||||
const vtuber = findVtuberJson.data[0]
|
||||
if (!vtuber) throw new Error('vtuber did not have an id. vtuber must have an id.')
|
||||
console.log('here is the findVtuberJson (as follows)')
|
||||
console.log(findVtuberJson)
|
||||
console.log(`the matching vtuber has ID=${vtuber.id} (${vtuber.attributes.displayName})`)
|
||||
}
|
||||
|
||||
if (!vtuberId) {
|
||||
console.log('>> vtuberId was not found so we create')
|
||||
|
||||
/**
|
||||
* We are creating a vtuber record.
|
||||
* We need a few things.
|
||||
* * image URL
|
||||
* * themeColor
|
||||
*
|
||||
* To get an image, we have to do a few things.
|
||||
* * [x] download image from platform
|
||||
* * [x] get themeColor from image
|
||||
* * [x] upload image to b2
|
||||
* * [x] get B2 cdn link to image
|
||||
*
|
||||
* To get themeColor, we need the image locally where we can then run
|
||||
*/
|
||||
|
||||
// download image from platform
|
||||
// vtuber.getImage expects a vtuber object, which we don't have yet, so we create a dummy one
|
||||
const dummyVtuber: IVtuber = {
|
||||
id: 69,
|
||||
attributes: {
|
||||
slug: fpSlugify(channel),
|
||||
displayName: 'example',
|
||||
vods: [],
|
||||
description1: ' ',
|
||||
image: ' ',
|
||||
themeColor: ' ',
|
||||
fanslyId: (platform === 'fansly') ? (userId ? userId : undefined) : undefined
|
||||
}
|
||||
}
|
||||
const imageFile = await getImage(dummyVtuber)
|
||||
|
||||
// get themeColor from image
|
||||
const themeColor = await getProminentColor(imageFile)
|
||||
|
||||
// upload image to b2
|
||||
const b2FileData = await uploadFile(imageFile)
|
||||
|
||||
// get b2 cdn link to image
|
||||
const imageCdnLink = `${process.env.CDN_BUCKET_URL}/${b2FileData.Key}`
|
||||
|
||||
console.log(`>>> createVtuberRes here we go 3-2-1, POST!`)
|
||||
const createVtuberRes = await fetch(`${process.env.STRAPI_URL}/api/vtubers`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'authorization': `Bearer ${process.env.SCOUT_STRAPI_API_KEY}`,
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
data: {
|
||||
displayName: channel,
|
||||
fansly: (platform === 'fansly') ? url : null,
|
||||
fanslyId: (platform === 'fansly') ? userId : null,
|
||||
chaturbate: (platform === 'chaturbate') ? url : null,
|
||||
slug: fpSlugify(channel),
|
||||
description1: ' ',
|
||||
image: imageCdnLink,
|
||||
themeColor: themeColor || '#dde1ec'
|
||||
}
|
||||
})
|
||||
})
|
||||
const createVtuberJson = await createVtuberRes.json() as IVtuberResponse
|
||||
console.log('>> createVtuberJson as follows')
|
||||
console.log(JSON.stringify(createVtuberJson, null, 2))
|
||||
if (createVtuberJson.data) {
|
||||
vtuberId = createVtuberJson.data.id
|
||||
console.log(`>>> vtuber created with id=${vtuberId}`)
|
||||
}
|
||||
}
|
||||
if (!vtuberId) throw new Error(`upsertVtuber failed to produce a vtuberId! This should not happen under normal circumstances.`);
|
||||
return vtuberId
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
import { proxyActivities, sleep, log } from '@temporalio/workflow';
|
||||
import { NotificationData } from '@futureporn/types';
|
||||
// Only import the activity types
|
||||
import type * as upsertVtuberType from './activities/upsertVtuber.js';
|
||||
import type * as upsertStreamType from './activities/upsertStream.js';
|
||||
import type * as upsertPlatformNotificationType from './activities/upsertPlatformNotification.js';
|
||||
|
||||
const { upsertVtuber } = proxyActivities<typeof upsertVtuberType>({
|
||||
startToCloseTimeout: '1 minute',
|
||||
});
|
||||
const { upsertStream } = proxyActivities<typeof upsertStreamType>({
|
||||
startToCloseTimeout: '1 minute',
|
||||
});
|
||||
const { upsertPlatformNotification } = proxyActivities<typeof upsertPlatformNotificationType>({
|
||||
startToCloseTimeout: '1 minute',
|
||||
});
|
||||
|
||||
export async function processNotifEmail(args: NotificationData): Promise<string> {
|
||||
return '@todo @todo @todo'
|
||||
// const { url, platform, channel, displayName, date, userId, avatar } = args
|
||||
// log.info('Hello from processNotifEmail workflow');
|
||||
// const vtuberId = await upsertVtuber({ platform, userId, url, channel });
|
||||
// const pNotifId = await upsertPlatformNotification({ source: 'email', date, platform, vtuberId });
|
||||
// const streamId = await upsertStream({ date, vtuberId, platform, pNotifId });
|
||||
// return `vtuberId: ${vtuberId} | pNotifId: ${pNotifId} | streamId: ${streamId}`;
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
this was copied over from fp/scout once I realized that there was a temporal recommended way to do workflows at the packages level.
|
|
@ -1,121 +0,0 @@
|
|||
import fetch from "node-fetch"
|
||||
import { NotificationData, processEmail } from "./workflows.js"
|
||||
import qs from 'qs'
|
||||
import { IPlatformNotificationResponse, IVtuberResponse, IStreamResponse } from 'next'
|
||||
import { getImage } from '../vtuber.js'
|
||||
import { fpSlugify } from '../utils.js'
|
||||
import { getProminentColor } from '../image.js'
|
||||
import { uploadFile } from '../s3.js'
|
||||
import { addMinutes, subMinutes } from 'date-fns'
|
||||
|
||||
export type ChargeResult = {
|
||||
status: string;
|
||||
errorMessage?: string;
|
||||
};
|
||||
|
||||
|
||||
if (!process.env.SCOUT_STRAPI_API_KEY) throw new Error('SCOUT_STRAPI_API_KEY is missing from env');
|
||||
if (!process.env.STRAPI_URL) throw new Error('STRAPI_URL is missing from env');
|
||||
if (!process.env.CDN_BUCKET_URL) throw new Error('CDN_BUCKET_URL is missing from env');
|
||||
if (!process.env.SCOUT_NITTER_URL) throw new Error('SCOUT_NITTER_URL is missing from env');
|
||||
if (!process.env.SCOUT_NITTER_ACCESS_KEY) throw new Error('SCOUT_NITTER_ACCESS_KEY is missing from env');
|
||||
|
||||
|
||||
|
||||
|
||||
export async function upsertPlatformNotification({ source, date, platform, vtuberId }: { source: string, date: string, platform: string, vtuberId: number }): Promise<number> {
|
||||
if (!source) throw new Error(`upsertPlatformNotification requires source arg, but it was undefined`);
|
||||
if (!date) throw new Error(`upsertPlatformNotification requires date arg, but it was undefined`);
|
||||
if (!platform) throw new Error(`upsertPlatformNotification requires platform arg, but it was undefined`);
|
||||
if (!vtuberId) throw new Error(`upsertPlatformNotification requires vtuberId arg, but it was undefined`);
|
||||
|
||||
let pNotifId
|
||||
// # Step 2.
|
||||
// Next we create the platform-notification record.
|
||||
// This probably doesn't already exist, so we don't check for a pre-existing platform-notification.
|
||||
const pNotifPayload = {
|
||||
data: {
|
||||
source: source,
|
||||
date: date,
|
||||
date2: date,
|
||||
platform: platform,
|
||||
vtuber: vtuberId,
|
||||
}
|
||||
}
|
||||
console.log('pNotifPayload as follows')
|
||||
console.log(pNotifPayload)
|
||||
|
||||
const pNotifCreateRes = await fetch(`${process.env.STRAPI_URL}/api/platform-notifications`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'authorization': `Bearer ${process.env.SCOUT_STRAPI_API_KEY}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(pNotifPayload)
|
||||
})
|
||||
const pNotifData = await pNotifCreateRes.json() as IPlatformNotificationResponse
|
||||
if (pNotifData.error) {
|
||||
console.error('>> we failed to create platform-notification, there was an error in the response')
|
||||
console.error(JSON.stringify(pNotifData.error, null, 2))
|
||||
throw new Error(pNotifData.error)
|
||||
}
|
||||
console.log(`>> pNotifData (json response) is as follows`)
|
||||
console.log(pNotifData)
|
||||
if (!pNotifData.data?.id) throw new Error('failed to created pNotifData! The response was missing an id');
|
||||
|
||||
pNotifId = pNotifData.data.id
|
||||
if (!pNotifId) throw new Error('failed to get Platform Notification ID');
|
||||
return pNotifId
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export async function chargeUser(
|
||||
userId: string,
|
||||
itemId: string,
|
||||
quantity: number,
|
||||
): Promise<ChargeResult> {
|
||||
// TODO send request to the payments service that looks up the user's saved
|
||||
// payment info and the cost of the item and attempts to charge their payment
|
||||
// method.
|
||||
console.log(`Charging user ${userId} for ${quantity} of item ${itemId}`);
|
||||
try {
|
||||
const response = await fetch("http://httpbin.org/get?status=success");
|
||||
const body: any = await response.json();
|
||||
return { status: body.args.status };
|
||||
} catch (e: any) {
|
||||
return { status: "failure", errorMessage: e.message };
|
||||
}
|
||||
}
|
||||
|
||||
export async function checkAndDecrementInventory(
|
||||
itemId: string,
|
||||
quantity: number,
|
||||
): Promise<boolean> {
|
||||
// TODO a database request that—in a single operation or transaction—checks
|
||||
// whether there are `quantity` items remaining, and if so, decreases the
|
||||
// total. Something like:
|
||||
// const result = await db.collection('items').updateOne(
|
||||
// { _id: itemId, numAvailable: { $gte: quantity } },
|
||||
// { $inc: { numAvailable: -quantity } }
|
||||
// )
|
||||
// return result.modifiedCount === 1
|
||||
console.log(`Reserving ${quantity} of item ${itemId}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function incrementInventory(
|
||||
itemId: string,
|
||||
quantity: number,
|
||||
): Promise<boolean> {
|
||||
// TODO increment inventory:
|
||||
// const result = await db.collection('items').updateOne(
|
||||
// { _id: itemId },
|
||||
// { $inc: { numAvailable: quantity } }
|
||||
// )
|
||||
// return result.modifiedCount === 1
|
||||
console.log(`Incrementing ${itemId} inventory by ${quantity}`);
|
||||
return true;
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
import path from "path"
|
||||
import { NativeConnection, Worker } from "@temporalio/worker"
|
||||
import * as activities from "./activities.js"
|
||||
import pRetry from 'p-retry'
|
||||
|
||||
|
||||
if (!process.env.TEMPORAL_SERVICE_ADDRESS) throw new Error(`TEMPORAL_SERVICE_ADDRESS is missing in env`);
|
||||
if (!process.env.TEMPORAL_NAMESPACE) throw new Error(`TEMPORAL_NAMESPACE is missing in env`);
|
||||
if (!process.env.TEMPORAL_TASK_QUEUE) throw new Error(`TEMPORAL_TASK_QUEUE is missing in env`);
|
||||
|
||||
|
||||
console.log(`
|
||||
process.env.TEMPORAL_SERVICE_ADDRESS=${process.env.TEMPORAL_SERVICE_ADDRESS}
|
||||
process.env.TEMPORAL_NAMESPACE=${process.env.TEMPORAL_NAMESPACE}
|
||||
process.env.TEMPORAL_TASK_QUEUE=${process.env.TEMPORAL_TASK_QUEUE}
|
||||
import.meta.dirname=${import.meta.dirname}
|
||||
`)
|
||||
|
||||
|
||||
async function run() {
|
||||
console.log(' scout-worker startup!')
|
||||
// Step 1: Establish a connection with Temporal server.
|
||||
//
|
||||
// Worker code uses `@temporalio/worker.NativeConnection`.
|
||||
// (But in your application code it's `@temporalio/client.Connection`.)
|
||||
const connection = await NativeConnection.connect({
|
||||
address: process.env.TEMPORAL_SERVICE_ADDRESS,
|
||||
// TLS and gRPC metadata configuration goes here.
|
||||
});
|
||||
// Step 2: Register Workflows and Activities with the Worker.
|
||||
const worker = await Worker.create({
|
||||
connection,
|
||||
namespace: process.env.TEMPORAL_NAMESPACE,
|
||||
taskQueue: ''+process.env.TEMPORAL_TASK_QUEUE,
|
||||
// Workflows are registered using a path as they run in a separate JS context.
|
||||
workflowsPath: path.join(import.meta.dirname, './workflows.ts'),
|
||||
activities,
|
||||
maxTaskQueueActivitiesPerSecond: 1 // since we are acessing 3rd party API, we use this as a courtesy throttle
|
||||
});
|
||||
console.log('scout-worker is running.')
|
||||
|
||||
// Step 3: Start accepting tasks on the `hello-world` queue
|
||||
//
|
||||
// The worker runs until it encounters an unexpected error or the process receives a shutdown signal registered on
|
||||
// the SDK Runtime object.
|
||||
//
|
||||
// By default, worker logs are written via the Runtime logger to STDERR at INFO level.
|
||||
//
|
||||
// See https://typescript.temporal.io/api/classes/worker.Runtime#install to customize these defaults.
|
||||
await worker.run();
|
||||
}
|
||||
|
||||
await pRetry(run, {
|
||||
forever: true,
|
||||
onFailedAttempt: (e) => {
|
||||
console.error(e);
|
||||
console.error(`there was an error during scout-worker run(). run() will now restart.`)
|
||||
console.log(`P.S., check out these booba --> (.)(.)`)
|
||||
}
|
||||
})
|
|
@ -1,61 +0,0 @@
|
|||
import { proxyActivities, continueAsNew, log, sleep } from "@temporalio/workflow"
|
||||
import type * as activities from "./activities.js"
|
||||
import { FetchMessageObject } from 'imapflow'
|
||||
|
||||
// { isMatch, url, platform, channel, displayName, date, userId, avatar }
|
||||
|
||||
|
||||
const {
|
||||
upsertPlatformNotification,
|
||||
upsertStream,
|
||||
upsertVtuber,
|
||||
} = proxyActivities<typeof activities>({
|
||||
startToCloseTimeout: "1 minute",
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
export async function processEmail({
|
||||
url, platform, channel, displayName, date, userId, avatar
|
||||
}: NotificationData): Promise<{ vtuberId: number, pNotifId: number, streamId: number }> {
|
||||
console.log(`processEmail begin. platform=${platform}, date=${date}, url=${url}`)
|
||||
// * In Strapi, we are finding or updating or creating the following content-types.
|
||||
// * * vtuber
|
||||
// * * platform-notification
|
||||
// * * stream
|
||||
// Step 1
|
||||
|
||||
const vtuberId = await upsertVtuber({ url, platform, channel, displayName, date, userId, avatar })
|
||||
console.log(` 🤠 upsertVtuber has completed, and the vtuberId=${vtuberId}`)
|
||||
const pNotifId = await upsertPlatformNotification({ vtuberId, source: 'email', date, platform })
|
||||
const streamId = await upsertStream({ date, vtuberId, platform, pNotifId })
|
||||
|
||||
return { vtuberId, pNotifId, streamId }
|
||||
}
|
||||
|
||||
// export async function order(
|
||||
// userId: string,
|
||||
// itemId: string,
|
||||
// quantity: number,
|
||||
// ): Promise<string> {
|
||||
// const haveEnoughInventory: boolean = await checkAndDecrementInventory(
|
||||
// itemId,
|
||||
// quantity,
|
||||
// );
|
||||
// if (haveEnoughInventory) {
|
||||
// const result: activities.ChargeResult = await chargeUser(
|
||||
// userId,
|
||||
// itemId,
|
||||
// quantity,
|
||||
// );
|
||||
// if (result.status === "success") {
|
||||
// return `Order successful!`;
|
||||
// } else {
|
||||
// await incrementInventory(itemId, quantity);
|
||||
// return `Unable to complete payment. Error: ${result.errorMessage}`;
|
||||
// }
|
||||
// } else {
|
||||
// return `Sorry, we don't have enough items in stock to fulfill your order.`;
|
||||
// }
|
||||
// }
|
|
@ -1,6 +0,0 @@
|
|||
import { log } from '@temporalio/activity';
|
||||
|
||||
export async function activityA(name: string): Promise<string> {
|
||||
log.info('hello from activityA', { name });
|
||||
return `ActivityA result: A-${name}!`;
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
import { log } from '@temporalio/activity';
|
||||
|
||||
export async function activityB(name: string): Promise<string> {
|
||||
log.info('hello from activityB', { name });
|
||||
return `ActivityB result: B-${name}!`;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
import { proxyActivities, sleep, log } from '@temporalio/workflow';
|
||||
// Only import the activity types
|
||||
import type * as activitiesA from './activities/activitiesA.js';
|
||||
import type * as activitiesB from './activities/activitiesB.js';
|
||||
|
||||
const { activityA } = proxyActivities<typeof activitiesA>({
|
||||
startToCloseTimeout: '1 minute',
|
||||
});
|
||||
const { activityB } = proxyActivities<typeof activitiesB>({
|
||||
startToCloseTimeout: '1 minute',
|
||||
});
|
||||
|
||||
export async function WorkflowA(name: string): Promise<string> {
|
||||
log.info('Hello from WorkflowA');
|
||||
const res1 = await activityA(name);
|
||||
await sleep(100);
|
||||
const res2 = await activityB(name);
|
||||
return `A: ${res1} | B: ${res2}`;
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
import { log } from '@temporalio/activity';
|
||||
|
||||
export async function activityC(name: string): Promise<string> {
|
||||
log.info('hello from activityC', { name });
|
||||
return `ActivityC result: C-${name}!`;
|
||||
}
|
||||
|
||||
export async function activityD(name: string): Promise<string> {
|
||||
log.info('hello from activityD', { name });
|
||||
return `ActivityD result: D-${name}!`;
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
import { proxyActivities, sleep, log } from '@temporalio/workflow';
|
||||
// Only import the activity types
|
||||
import type * as activities from './activities.js';
|
||||
|
||||
const { activityC, activityD } = proxyActivities<typeof activities>({
|
||||
startToCloseTimeout: '1 minute',
|
||||
});
|
||||
|
||||
export async function WorkflowB(name = 'WorkflowB'): Promise<string> {
|
||||
log.info('Hello from WorkflowB');
|
||||
const res1 = await activityC(name);
|
||||
await sleep(100);
|
||||
const res2 = await activityD(name);
|
||||
return `${res1} ${res2}`;
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
export * from './workflowA/workflow.js'
|
||||
// export * from './workflowB/workflow.js'
|
||||
// export * from './processNotifEmail/workflow.js'
|
|
@ -1,33 +0,0 @@
|
|||
{
|
||||
"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,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
// Transpile our TypeScript code to JavaScript
|
||||
"module": "NodeNext",
|
||||
"outDir": "./dist",
|
||||
"lib": [
|
||||
"es2022"
|
||||
],
|
||||
"rootDir": "src"
|
||||
},
|
||||
// Include the necessary files for your project
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
"description": "",
|
||||
"main": "index.js",
|
||||
"exports": {
|
||||
"./*.js": "./src/*.js"
|
||||
"./*.ts": "./src/*.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Warn: no test specified\" && exit 0",
|
||||
|
@ -16,10 +16,11 @@
|
|||
"author": "@CJ_Clippy",
|
||||
"license": "Unlicense",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.583.0",
|
||||
"@aws-sdk/lib-storage": "^3.588.0",
|
||||
"@aws-sdk/client-s3": "^3.637.0",
|
||||
"@aws-sdk/lib-storage": "^3.637.0",
|
||||
"@futureporn/types": "workspace:^",
|
||||
"@paralleldrive/cuid2": "^2.2.2",
|
||||
"@types/node": "^20.14.9",
|
||||
"@types/node": "^22.5.2",
|
||||
"dotenv": "^16.4.5"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,17 +9,20 @@ importers:
|
|||
.:
|
||||
dependencies:
|
||||
'@aws-sdk/client-s3':
|
||||
specifier: ^3.583.0
|
||||
specifier: ^3.637.0
|
||||
version: 3.637.0
|
||||
'@aws-sdk/lib-storage':
|
||||
specifier: ^3.588.0
|
||||
specifier: ^3.637.0
|
||||
version: 3.637.0(@aws-sdk/client-s3@3.637.0)
|
||||
'@futureporn/types':
|
||||
specifier: workspace:^
|
||||
version: link:../types
|
||||
'@paralleldrive/cuid2':
|
||||
specifier: ^2.2.2
|
||||
version: 2.2.2
|
||||
'@types/node':
|
||||
specifier: ^20.14.9
|
||||
version: 20.16.1
|
||||
specifier: ^22.5.2
|
||||
version: 22.5.2
|
||||
dotenv:
|
||||
specifier: ^16.4.5
|
||||
version: 16.4.5
|
||||
|
@ -195,9 +198,9 @@ packages:
|
|||
resolution: {integrity: sha512-l9XxNcA4HX98rwCC2/KoiWcmEiRfZe4G+mYwDbCFT87JIMj6GBhLDkAzr/W8KAaA2IDr8Vc6J8fZPgVulxxfMA==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
|
||||
'@noble/hashes@1.4.0':
|
||||
resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==}
|
||||
engines: {node: '>= 16'}
|
||||
'@noble/hashes@1.5.0':
|
||||
resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==}
|
||||
engines: {node: ^14.21.3 || >=16}
|
||||
|
||||
'@paralleldrive/cuid2@2.2.2':
|
||||
resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==}
|
||||
|
@ -405,8 +408,8 @@ packages:
|
|||
resolution: {integrity: sha512-4pP0EV3iTsexDx+8PPGAKCQpd/6hsQBaQhqWzU4hqKPHN5epPsxKbvUTIiYIHTxaKt6/kEaqPBpu/ufvfbrRzw==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
|
||||
'@types/node@20.16.1':
|
||||
resolution: {integrity: sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==}
|
||||
'@types/node@22.5.2':
|
||||
resolution: {integrity: sha512-acJsPTEqYqulZS/Yp/S3GgeE6GZ0qYODUR8aVr/DkhHQ8l9nd4j5x1/ZJy9/gHrRlFMqkO6i0I3E27Alu4jjPg==}
|
||||
|
||||
base64-js@1.5.1:
|
||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||
|
@ -969,11 +972,11 @@ snapshots:
|
|||
'@smithy/types': 3.3.0
|
||||
tslib: 2.7.0
|
||||
|
||||
'@noble/hashes@1.4.0': {}
|
||||
'@noble/hashes@1.5.0': {}
|
||||
|
||||
'@paralleldrive/cuid2@2.2.2':
|
||||
dependencies:
|
||||
'@noble/hashes': 1.4.0
|
||||
'@noble/hashes': 1.5.0
|
||||
|
||||
'@smithy/abort-controller@3.1.1':
|
||||
dependencies:
|
||||
|
@ -1306,7 +1309,7 @@ snapshots:
|
|||
'@smithy/types': 3.3.0
|
||||
tslib: 2.7.0
|
||||
|
||||
'@types/node@20.16.1':
|
||||
'@types/node@22.5.2':
|
||||
dependencies:
|
||||
undici-types: 6.19.8
|
||||
|
||||
|
|
|
@ -1,33 +1,88 @@
|
|||
import dotenv from 'dotenv';
|
||||
dotenv.config({
|
||||
path: '../../.env',
|
||||
});
|
||||
|
||||
import { S3Client, type S3ClientConfig } from "@aws-sdk/client-s3";
|
||||
import { S3Client, GetObjectCommand, type S3ClientConfig } from "@aws-sdk/client-s3";
|
||||
import { Upload } from "@aws-sdk/lib-storage";
|
||||
import type { S3FileResponse, S3FileRecord, Stream } from '@futureporn/types';
|
||||
import { createId } from '@paralleldrive/cuid2';
|
||||
import { basename } from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import fs, { createWriteStream, createReadStream } from 'node:fs';
|
||||
import { type Readable, pipeline } from "node:stream";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { promisify } from "node:util";
|
||||
|
||||
if (!process.env.S3_BUCKET_NAME) throw new Error('S3_BUCKET_NAME was undefined in env');
|
||||
if (!process.env.SCOUT_NITTER_URL) throw new Error('SCOUT_NITTER_URL was undefined in env');
|
||||
if (!process.env.S3_BUCKET_KEY_ID) throw new Error('S3_BUCKET_KEY_ID was undefined in env');
|
||||
if (!process.env.S3_BUCKET_APPLICATION_KEY) throw new Error('S3_BUCKET_APPLICATION_KEY was undefined in env');
|
||||
export interface S3FileArgs {
|
||||
filePath: string;
|
||||
s3BucketName: string;
|
||||
s3AccessKeyId: string;
|
||||
s3SecretAccessKey: string;
|
||||
s3Region: string;
|
||||
s3Endpoint: string;
|
||||
}
|
||||
|
||||
export async function uploadFile(filePath: string): Promise<any> {
|
||||
if (!filePath) throw new Error("first argument, 'filePath' is undefined");
|
||||
export const s3CdnMap = new Map([
|
||||
['futureporn', 'https://futureporn-b2.b-cdn.net'],
|
||||
['fp-usc-dev', 'https://fp-usc-dev.b-cdn.net'],
|
||||
])
|
||||
|
||||
function assertArguments(args: any): asserts args is S3FileArgs {
|
||||
if (typeof args!== "object" ||!args) throw new Error("invalid S3FileArgs");
|
||||
if (!args.filePath) throw new Error('filePath was missing from args');
|
||||
if (typeof args.filePath!== 'string') throw new Error('filePath must be a string');
|
||||
if (!args.s3BucketName) throw new Error('s3BucketName was missing from args');
|
||||
if (typeof args.s3BucketName!== 'string') throw new Error('s3BucketName must be a string');
|
||||
if (!args.s3AccessKeyId) throw new Error('s3AccessKeyId was missing from args');
|
||||
if (typeof args.s3AccessKeyId!== 'string') throw new Error('s3AccessKeyId must be a string');
|
||||
if (!args.s3SecretAccessKey) throw new Error('s3SecretAccessKey was missing from args');
|
||||
if (typeof args.s3SecretAccessKey!== 'string') throw new Error('s3SecretAccessKey must be a string');
|
||||
if (!args.s3Region) throw new Error('s3Region was missing from args');
|
||||
if (typeof args.s3Region!== 'string') throw new Error('s3Region must be a string');
|
||||
if (!args.s3Endpoint) throw new Error('s3Endpoint was missing from args');
|
||||
if (typeof args.s3Endpoint!== 'string') throw new Error('s3Endpoint must be a string');
|
||||
}
|
||||
|
||||
export function getCdnUrl(bucket: string, key: string): string {
|
||||
if (!bucket) throw new Error('getCdnUrl() first arg (bucket name) was missing');
|
||||
if (!bucket) throw new Error('getCdnUrl() second arg (key) was missing');
|
||||
return `${s3CdnMap.get(bucket)}/${key}`
|
||||
}
|
||||
|
||||
// export async function downloadFile(args: S3FileArgs) {
|
||||
// assertArguments(args)
|
||||
// const { filePath, s3AccessKeyId, s3SecretAccessKey, s3BucketName, s3Endpoint, s3Region } = args
|
||||
// // throw new Error('@todo')
|
||||
// const download = S3Client
|
||||
// }
|
||||
|
||||
|
||||
export async function downloadFile (client: S3Client, bucket: string, s3_key: string): Promise<string> {
|
||||
console.log(`downloadS3File with s3File s3_key=${s3_key}, bucket=${bucket}`)
|
||||
const getObjectCommand = new GetObjectCommand({ Bucket: bucket, Key: s3_key })
|
||||
const response = await client.send(getObjectCommand)
|
||||
if (!response) throw new Error(`failed to receive a response while calling S3 GetObjectCommand (within downloadS3File)`);
|
||||
if (!response.Body) throw new Error('S3 GetObjectCommand response did not have a Body (within downloadS3File)');
|
||||
const readStream = response.Body as Readable
|
||||
const outputFilePath = join(tmpdir(), s3_key)
|
||||
const writeStream = createWriteStream(outputFilePath)
|
||||
const pipelinePromise = promisify(pipeline)
|
||||
await pipelinePromise(readStream, writeStream)
|
||||
return outputFilePath
|
||||
}
|
||||
|
||||
export async function uploadFile(args: unknown) {
|
||||
assertArguments(args)
|
||||
const { filePath, s3AccessKeyId, s3SecretAccessKey, s3BucketName, s3Endpoint, s3Region } = args;
|
||||
const options: S3ClientConfig = {
|
||||
endpoint: 'https://s3.us-west-000.backblazeb2.com',
|
||||
region: 'us-west-000',
|
||||
endpoint: s3Endpoint,
|
||||
region: s3Region,
|
||||
credentials: {
|
||||
accessKeyId: process.env.S3_BUCKET_KEY_ID!,
|
||||
secretAccessKey: process.env.S3_BUCKET_APPLICATION_KEY!,
|
||||
accessKeyId: s3AccessKeyId,
|
||||
secretAccessKey: s3SecretAccessKey,
|
||||
},
|
||||
}
|
||||
const client = new S3Client();
|
||||
const client = new S3Client(options);
|
||||
const key = `${createId()}-${basename(filePath)}`
|
||||
const target = {
|
||||
Bucket: process.env.S3_BUCKET_NAME,
|
||||
Key: `${createId()}-${basename(filePath)}`,
|
||||
Bucket: s3BucketName,
|
||||
Key: key,
|
||||
Body: fs.createReadStream(filePath),
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
// Base Options recommended for all projects
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"target": "es2022",
|
||||
|
@ -22,7 +22,6 @@
|
|||
// Include the necessary files for your project
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
"**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
# @futureporn/taco
|
||||
|
||||
A test package to better understand Internal TypeScript Packages [[1](https://github.com/0x80/isolate-package?tab=readme-ov-file#the-internal-packages-strategy)] [[2](https://turbo.build/blog/you-might-not-need-typescript-project-references)] [[3](https://www.typescriptlang.org/docs/handbook/project-references.html)]
|
||||
|
||||
The TL;DR: The consuming application of an internal package must transpile and typecheck it.
|
||||
|
||||
In this example, @futureporn/meal consumes @futureporn/taco. A build step happens only in @futureporn/meal.
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"name": "@futureporn/taco",
|
||||
"type": "module",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"scripts": {
|
||||
"test": "echo \"Warn: no test specified\" && exit 0"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "@CJ_Clippy",
|
||||
"license": "Unlicense"
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
lockfileVersion: '9.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
importers:
|
||||
|
||||
.: {}
|
|
@ -1,19 +0,0 @@
|
|||
|
||||
|
||||
export type Taco = {
|
||||
meat: Boolean;
|
||||
cheese: Boolean;
|
||||
lettuce: Boolean;
|
||||
salsa: Boolean;
|
||||
crunchy: Boolean;
|
||||
}
|
||||
|
||||
export function taco(): Taco {
|
||||
return {
|
||||
meat: true,
|
||||
cheese: false,
|
||||
lettuce: true,
|
||||
salsa: true,
|
||||
crunchy: true
|
||||
}
|
||||
}
|
|
@ -13,6 +13,6 @@
|
|||
"author": "",
|
||||
"license": "Unlicense",
|
||||
"devDependencies": {
|
||||
"typescript": "^5.5.3"
|
||||
"typescript": "^5.5.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ importers:
|
|||
.:
|
||||
devDependencies:
|
||||
typescript:
|
||||
specifier: ^5.5.3
|
||||
specifier: ^5.5.4
|
||||
version: 5.5.4
|
||||
|
||||
packages:
|
||||
|
|
|
@ -7,7 +7,13 @@ export type ProcessingState = 'processing'
|
|||
export type WaitingState = 'pending_recording'
|
||||
export type Status = Partial<WaitingState | ProcessingState | RecordingState>
|
||||
|
||||
export interface S3File {
|
||||
export interface S3FileRecord {
|
||||
s3_key: string;
|
||||
s3_id?: string;
|
||||
bucket: string;
|
||||
}
|
||||
|
||||
export interface S3FileResponse {
|
||||
s3_key: string;
|
||||
s3_id?: string;
|
||||
bucket: string;
|
||||
|
@ -104,7 +110,7 @@ export interface VodRecord {
|
|||
title?: string;
|
||||
date: string;
|
||||
mux_asset: MuxAssetRecord;
|
||||
thumbnail?: S3File;
|
||||
thumbnail?: S3FileRecord;
|
||||
vtuber: string;
|
||||
ipfs_cid?: string;
|
||||
torrent?: string;
|
||||
|
@ -113,6 +119,7 @@ export interface VodRecord {
|
|||
note?: string;
|
||||
url: string;
|
||||
discord_message_id: string;
|
||||
s3_file: string;
|
||||
}
|
||||
|
||||
export interface TagRecord {
|
||||
|
@ -248,9 +255,6 @@ export interface IPlatformNotificationResponse {
|
|||
error?: any;
|
||||
}
|
||||
|
||||
export interface Vod {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface IVodsResponse {
|
||||
id: string
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
"type": "module",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"exports": {
|
||||
"./*.ts": "./src/*.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha",
|
||||
"clean": "rm -rf dist",
|
||||
|
@ -15,17 +16,19 @@
|
|||
"license": "Unlicense",
|
||||
"dependencies": {
|
||||
"@paralleldrive/cuid2": "^2.2.2",
|
||||
"@types/node": "^20.14.9",
|
||||
"@types/slug": "^5.0.8",
|
||||
"p-retry": "^5.1.2",
|
||||
"@types/node": "^22.5.2",
|
||||
"@types/slug": "^5.0.9",
|
||||
"p-retry": "^6.2.0",
|
||||
"prevvy": "^8.0.1",
|
||||
"sharp": "^0.33.5",
|
||||
"slug": "^9.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "^4.3.16",
|
||||
"@types/chai": "^4.3.19",
|
||||
"@types/mocha": "^10.0.7",
|
||||
"chai": "^5.1.1",
|
||||
"mocha": "^10.6.0",
|
||||
"mocha": "^10.7.3",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsx": "^4.16.2"
|
||||
"tsx": "^4.19.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,21 +12,27 @@ importers:
|
|||
specifier: ^2.2.2
|
||||
version: 2.2.2
|
||||
'@types/node':
|
||||
specifier: ^20.14.9
|
||||
version: 20.16.1
|
||||
specifier: ^22.5.2
|
||||
version: 22.5.2
|
||||
'@types/slug':
|
||||
specifier: ^5.0.8
|
||||
specifier: ^5.0.9
|
||||
version: 5.0.9
|
||||
p-retry:
|
||||
specifier: ^5.1.2
|
||||
version: 5.1.2
|
||||
specifier: ^6.2.0
|
||||
version: 6.2.0
|
||||
prevvy:
|
||||
specifier: ^8.0.1
|
||||
version: 8.0.1
|
||||
sharp:
|
||||
specifier: ^0.33.5
|
||||
version: 0.33.5
|
||||
slug:
|
||||
specifier: ^9.1.0
|
||||
version: 9.1.0
|
||||
devDependencies:
|
||||
'@types/chai':
|
||||
specifier: ^4.3.16
|
||||
version: 4.3.17
|
||||
specifier: ^4.3.19
|
||||
version: 4.3.19
|
||||
'@types/mocha':
|
||||
specifier: ^10.0.7
|
||||
version: 10.0.7
|
||||
|
@ -34,14 +40,14 @@ importers:
|
|||
specifier: ^5.1.1
|
||||
version: 5.1.1
|
||||
mocha:
|
||||
specifier: ^10.6.0
|
||||
specifier: ^10.7.3
|
||||
version: 10.7.3
|
||||
ts-node:
|
||||
specifier: ^10.9.2
|
||||
version: 10.9.2(@types/node@20.16.1)(typescript@5.5.4)
|
||||
version: 10.9.2(@types/node@22.5.2)(typescript@5.5.4)
|
||||
tsx:
|
||||
specifier: ^4.16.2
|
||||
version: 4.17.0
|
||||
specifier: ^4.19.0
|
||||
version: 4.19.0
|
||||
|
||||
packages:
|
||||
|
||||
|
@ -49,6 +55,9 @@ packages:
|
|||
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@emnapi/runtime@1.2.0':
|
||||
resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==}
|
||||
|
||||
'@esbuild/aix-ppc64@0.23.1':
|
||||
resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
@ -193,6 +202,111 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@img/sharp-darwin-arm64@0.33.5':
|
||||
resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-darwin-x64@0.33.5':
|
||||
resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-darwin-arm64@1.0.4':
|
||||
resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-darwin-x64@1.0.4':
|
||||
resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-linux-arm64@1.0.4':
|
||||
resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.0.5':
|
||||
resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.0.4':
|
||||
resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.0.4':
|
||||
resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.0.4':
|
||||
resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.0.4':
|
||||
resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-arm64@0.33.5':
|
||||
resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-arm@0.33.5':
|
||||
resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-s390x@0.33.5':
|
||||
resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-x64@0.33.5':
|
||||
resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.33.5':
|
||||
resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.33.5':
|
||||
resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-wasm32@0.33.5':
|
||||
resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [wasm32]
|
||||
|
||||
'@img/sharp-win32-ia32@0.33.5':
|
||||
resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@img/sharp-win32-x64@0.33.5':
|
||||
resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@jridgewell/resolve-uri@3.1.2':
|
||||
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
@ -203,9 +317,9 @@ packages:
|
|||
'@jridgewell/trace-mapping@0.3.9':
|
||||
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
|
||||
|
||||
'@noble/hashes@1.4.0':
|
||||
resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==}
|
||||
engines: {node: '>= 16'}
|
||||
'@noble/hashes@1.5.0':
|
||||
resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==}
|
||||
engines: {node: ^14.21.3 || >=16}
|
||||
|
||||
'@paralleldrive/cuid2@2.2.2':
|
||||
resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==}
|
||||
|
@ -222,17 +336,32 @@ packages:
|
|||
'@tsconfig/node16@1.0.4':
|
||||
resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
|
||||
|
||||
'@types/chai@4.3.17':
|
||||
resolution: {integrity: sha512-zmZ21EWzR71B4Sscphjief5djsLre50M6lI622OSySTmn9DB3j+C3kWroHfBQWXbOBwbgg/M8CG/hUxDLIloow==}
|
||||
'@types/chai@4.3.19':
|
||||
resolution: {integrity: sha512-2hHHvQBVE2FiSK4eN0Br6snX9MtolHaTo/batnLjlGRhoQzlCL61iVpxoqO7SfFyOw+P/pwv+0zNHzKoGWz9Cw==}
|
||||
|
||||
'@types/debug@4.1.12':
|
||||
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
||||
|
||||
'@types/fluent-ffmpeg@2.1.26':
|
||||
resolution: {integrity: sha512-0JVF3wdQG+pN0ImwWD0bNgJiKF2OHg/7CDBHw5UIbRTvlnkgGHK6V5doE54ltvhud4o31/dEiHm23CAlxFiUQg==}
|
||||
|
||||
'@types/luxon@3.4.2':
|
||||
resolution: {integrity: sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==}
|
||||
|
||||
'@types/mocha@10.0.7':
|
||||
resolution: {integrity: sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==}
|
||||
|
||||
'@types/node@20.16.1':
|
||||
resolution: {integrity: sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==}
|
||||
'@types/ms@0.7.34':
|
||||
resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==}
|
||||
|
||||
'@types/retry@0.12.1':
|
||||
resolution: {integrity: sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==}
|
||||
'@types/node@20.16.3':
|
||||
resolution: {integrity: sha512-/wdGiWRkMOm53gAsSyFMXFZHbVg7C6CbkrzHNpaHoYfsUWPg7m6ZRKtvQjgvQ9i8WT540a3ydRlRQbxjY30XxQ==}
|
||||
|
||||
'@types/node@22.5.2':
|
||||
resolution: {integrity: sha512-acJsPTEqYqulZS/Yp/S3GgeE6GZ0qYODUR8aVr/DkhHQ8l9nd4j5x1/ZJy9/gHrRlFMqkO6i0I3E27Alu4jjPg==}
|
||||
|
||||
'@types/retry@0.12.2':
|
||||
resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==}
|
||||
|
||||
'@types/slug@5.0.9':
|
||||
resolution: {integrity: sha512-6Yp8BSplP35Esa/wOG1wLNKiqXevpQTEF/RcL/NV6BBQaMmZh4YlDwCgrrFSoUE4xAGvnKd5c+lkQJmPrBAzfQ==}
|
||||
|
@ -272,6 +401,9 @@ packages:
|
|||
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
async@0.2.10:
|
||||
resolution: {integrity: sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==}
|
||||
|
||||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
|
@ -319,9 +451,20 @@ packages:
|
|||
color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
|
||||
color-string@1.9.1:
|
||||
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
|
||||
|
||||
color@4.2.3:
|
||||
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
|
||||
engines: {node: '>=12.5.0'}
|
||||
|
||||
create-require@1.1.1:
|
||||
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
|
||||
|
||||
cross-spawn@7.0.3:
|
||||
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
debug@4.3.6:
|
||||
resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==}
|
||||
engines: {node: '>=6.0'}
|
||||
|
@ -339,6 +482,10 @@ packages:
|
|||
resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
detect-libc@2.0.3:
|
||||
resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
diff@4.0.2:
|
||||
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
|
||||
engines: {node: '>=0.3.1'}
|
||||
|
@ -355,14 +502,18 @@ packages:
|
|||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
escalade@3.1.2:
|
||||
resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
|
||||
escalade@3.2.0:
|
||||
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
escape-string-regexp@4.0.0:
|
||||
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
execa@8.0.1:
|
||||
resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
|
||||
engines: {node: '>=16.17'}
|
||||
|
||||
fill-range@7.1.1:
|
||||
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -375,6 +526,10 @@ packages:
|
|||
resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
|
||||
hasBin: true
|
||||
|
||||
fluent-ffmpeg@2.1.3:
|
||||
resolution: {integrity: sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
fs.realpath@1.0.0:
|
||||
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
||||
|
||||
|
@ -390,8 +545,12 @@ packages:
|
|||
get-func-name@2.0.2:
|
||||
resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
|
||||
|
||||
get-tsconfig@4.7.6:
|
||||
resolution: {integrity: sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==}
|
||||
get-stream@8.0.1:
|
||||
resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
get-tsconfig@4.8.0:
|
||||
resolution: {integrity: sha512-Pgba6TExTZ0FJAn1qkJAjIeKoDJ3CsI2ChuLohJnZl/tTU8MVrq3b+2t5UOPfRa4RMsorClBjJALkJUMjG1PAw==}
|
||||
|
||||
glob-parent@5.1.2:
|
||||
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
||||
|
@ -410,6 +569,10 @@ packages:
|
|||
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
|
||||
hasBin: true
|
||||
|
||||
human-signals@5.0.0:
|
||||
resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
|
||||
engines: {node: '>=16.17.0'}
|
||||
|
||||
inflight@1.0.6:
|
||||
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
|
||||
deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
|
||||
|
@ -417,6 +580,9 @@ packages:
|
|||
inherits@2.0.4:
|
||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||
|
||||
is-arrayish@0.3.2:
|
||||
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
|
||||
|
||||
is-binary-path@2.1.0:
|
||||
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -433,6 +599,10 @@ packages:
|
|||
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
is-network-error@1.1.0:
|
||||
resolution: {integrity: sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
is-number@7.0.0:
|
||||
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
|
||||
engines: {node: '>=0.12.0'}
|
||||
|
@ -441,10 +611,17 @@ packages:
|
|||
resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
is-stream@3.0.0:
|
||||
resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
|
||||
is-unicode-supported@0.1.0:
|
||||
resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
isexe@2.0.0:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
|
||||
js-yaml@4.1.0:
|
||||
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
|
||||
hasBin: true
|
||||
|
@ -460,9 +637,19 @@ packages:
|
|||
loupe@3.1.1:
|
||||
resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==}
|
||||
|
||||
luxon@1.28.1:
|
||||
resolution: {integrity: sha512-gYHAa180mKrNIUJCbwpmD0aTu9kV0dREDrwNnuyFAsO1Wt0EVYSZelPnJlbj9HplzXX/YWXHFTL45kvZ53M0pw==}
|
||||
|
||||
make-error@1.3.6:
|
||||
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
|
||||
|
||||
merge-stream@2.0.0:
|
||||
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
|
||||
|
||||
mimic-fn@4.0.0:
|
||||
resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
minimatch@5.1.6:
|
||||
resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
|
||||
engines: {node: '>=10'}
|
||||
|
@ -482,9 +669,17 @@ packages:
|
|||
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
npm-run-path@5.3.0:
|
||||
resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
|
||||
once@1.4.0:
|
||||
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||
|
||||
onetime@6.0.0:
|
||||
resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
p-limit@3.1.0:
|
||||
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
@ -493,14 +688,22 @@ packages:
|
|||
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
|
||||
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}
|
||||
p-retry@6.2.0:
|
||||
resolution: {integrity: sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==}
|
||||
engines: {node: '>=16.17'}
|
||||
|
||||
path-exists@4.0.0:
|
||||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
path-key@3.1.1:
|
||||
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
path-key@4.0.0:
|
||||
resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
pathval@2.0.0:
|
||||
resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
|
||||
engines: {node: '>= 14.16'}
|
||||
|
@ -509,6 +712,9 @@ packages:
|
|||
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
|
||||
engines: {node: '>=8.6'}
|
||||
|
||||
prevvy@8.0.1:
|
||||
resolution: {integrity: sha512-ztl6JrbdlICy9cBOxN/aVcT8bp8G08SXMUPns/MJvHHMB6cc3goJiTQwTGLL0X2PoMUYr31YZgd6X6k87NU4OQ==}
|
||||
|
||||
randombytes@2.1.0:
|
||||
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
|
||||
|
||||
|
@ -530,9 +736,33 @@ packages:
|
|||
safe-buffer@5.2.1:
|
||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||
|
||||
semver@7.6.3:
|
||||
resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
serialize-javascript@6.0.2:
|
||||
resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
|
||||
|
||||
sharp@0.33.5:
|
||||
resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
|
||||
shebang-command@2.0.0:
|
||||
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
shebang-regex@3.0.0:
|
||||
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
signal-exit@4.1.0:
|
||||
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
simple-swizzle@0.2.2:
|
||||
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
|
||||
|
||||
slug@9.1.0:
|
||||
resolution: {integrity: sha512-ioOsCfzQSu+D6NZ8XMCR8IW9FgvF8W7Xzz56hBkB/ALvNaWeBs2MUvvPugq3GCrxfHPFeK6hAxGkY/WLnfX2Lg==}
|
||||
hasBin: true
|
||||
|
@ -545,6 +775,10 @@ packages:
|
|||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
strip-final-newline@3.0.0:
|
||||
resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
strip-json-comments@3.1.1:
|
||||
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -575,8 +809,11 @@ packages:
|
|||
'@swc/wasm':
|
||||
optional: true
|
||||
|
||||
tsx@4.17.0:
|
||||
resolution: {integrity: sha512-eN4mnDA5UMKDt4YZixo9tBioibaMBpoxBkD+rIPAjVmYERSG0/dWEY1CEFuV89CgASlKL499q8AhmkMnnjtOJg==}
|
||||
tslib@2.7.0:
|
||||
resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==}
|
||||
|
||||
tsx@4.19.0:
|
||||
resolution: {integrity: sha512-bV30kM7bsLZKZIOCHeMNVMJ32/LuJzLVajkQI/qf92J2Qr08ueLQvW00PUZGiuLPP760UINwupgUj8qrSCPUKg==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
hasBin: true
|
||||
|
||||
|
@ -591,6 +828,15 @@ packages:
|
|||
v8-compile-cache-lib@3.0.1:
|
||||
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
|
||||
|
||||
which@1.3.1:
|
||||
resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==}
|
||||
hasBin: true
|
||||
|
||||
which@2.0.2:
|
||||
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
||||
engines: {node: '>= 8'}
|
||||
hasBin: true
|
||||
|
||||
workerpool@6.5.1:
|
||||
resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==}
|
||||
|
||||
|
@ -631,6 +877,11 @@ snapshots:
|
|||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.9
|
||||
|
||||
'@emnapi/runtime@1.2.0':
|
||||
dependencies:
|
||||
tslib: 2.7.0
|
||||
optional: true
|
||||
|
||||
'@esbuild/aix-ppc64@0.23.1':
|
||||
optional: true
|
||||
|
||||
|
@ -703,6 +954,81 @@ snapshots:
|
|||
'@esbuild/win32-x64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-darwin-arm64@0.33.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-arm64': 1.0.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-darwin-x64@0.33.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-x64': 1.0.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-darwin-arm64@1.0.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-darwin-x64@1.0.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-arm64@1.0.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.0.5':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.0.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.0.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.0.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.0.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-arm64@0.33.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-arm64': 1.0.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-arm@0.33.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-arm': 1.0.5
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-s390x@0.33.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-s390x': 1.0.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-x64@0.33.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-x64': 1.0.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.33.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linuxmusl-arm64': 1.0.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.33.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linuxmusl-x64': 1.0.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-wasm32@0.33.5':
|
||||
dependencies:
|
||||
'@emnapi/runtime': 1.2.0
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-ia32@0.33.5':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-x64@0.33.5':
|
||||
optional: true
|
||||
|
||||
'@jridgewell/resolve-uri@3.1.2': {}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.5.0': {}
|
||||
|
@ -712,11 +1038,11 @@ snapshots:
|
|||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.5.0
|
||||
|
||||
'@noble/hashes@1.4.0': {}
|
||||
'@noble/hashes@1.5.0': {}
|
||||
|
||||
'@paralleldrive/cuid2@2.2.2':
|
||||
dependencies:
|
||||
'@noble/hashes': 1.4.0
|
||||
'@noble/hashes': 1.5.0
|
||||
|
||||
'@tsconfig/node10@1.0.11': {}
|
||||
|
||||
|
@ -726,15 +1052,31 @@ snapshots:
|
|||
|
||||
'@tsconfig/node16@1.0.4': {}
|
||||
|
||||
'@types/chai@4.3.17': {}
|
||||
'@types/chai@4.3.19': {}
|
||||
|
||||
'@types/debug@4.1.12':
|
||||
dependencies:
|
||||
'@types/ms': 0.7.34
|
||||
|
||||
'@types/fluent-ffmpeg@2.1.26':
|
||||
dependencies:
|
||||
'@types/node': 22.5.2
|
||||
|
||||
'@types/luxon@3.4.2': {}
|
||||
|
||||
'@types/mocha@10.0.7': {}
|
||||
|
||||
'@types/node@20.16.1':
|
||||
'@types/ms@0.7.34': {}
|
||||
|
||||
'@types/node@20.16.3':
|
||||
dependencies:
|
||||
undici-types: 6.19.8
|
||||
|
||||
'@types/retry@0.12.1': {}
|
||||
'@types/node@22.5.2':
|
||||
dependencies:
|
||||
undici-types: 6.19.8
|
||||
|
||||
'@types/retry@0.12.2': {}
|
||||
|
||||
'@types/slug@5.0.9': {}
|
||||
|
||||
|
@ -763,6 +1105,8 @@ snapshots:
|
|||
|
||||
assertion-error@2.0.1: {}
|
||||
|
||||
async@0.2.10: {}
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
binary-extensions@2.3.0: {}
|
||||
|
@ -818,8 +1162,24 @@ snapshots:
|
|||
|
||||
color-name@1.1.4: {}
|
||||
|
||||
color-string@1.9.1:
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
simple-swizzle: 0.2.2
|
||||
|
||||
color@4.2.3:
|
||||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
color-string: 1.9.1
|
||||
|
||||
create-require@1.1.1: {}
|
||||
|
||||
cross-spawn@7.0.3:
|
||||
dependencies:
|
||||
path-key: 3.1.1
|
||||
shebang-command: 2.0.0
|
||||
which: 2.0.2
|
||||
|
||||
debug@4.3.6(supports-color@8.1.1):
|
||||
dependencies:
|
||||
ms: 2.1.2
|
||||
|
@ -830,6 +1190,8 @@ snapshots:
|
|||
|
||||
deep-eql@5.0.2: {}
|
||||
|
||||
detect-libc@2.0.3: {}
|
||||
|
||||
diff@4.0.2: {}
|
||||
|
||||
diff@5.2.0: {}
|
||||
|
@ -863,10 +1225,22 @@ snapshots:
|
|||
'@esbuild/win32-ia32': 0.23.1
|
||||
'@esbuild/win32-x64': 0.23.1
|
||||
|
||||
escalade@3.1.2: {}
|
||||
escalade@3.2.0: {}
|
||||
|
||||
escape-string-regexp@4.0.0: {}
|
||||
|
||||
execa@8.0.1:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.3
|
||||
get-stream: 8.0.1
|
||||
human-signals: 5.0.0
|
||||
is-stream: 3.0.0
|
||||
merge-stream: 2.0.0
|
||||
npm-run-path: 5.3.0
|
||||
onetime: 6.0.0
|
||||
signal-exit: 4.1.0
|
||||
strip-final-newline: 3.0.0
|
||||
|
||||
fill-range@7.1.1:
|
||||
dependencies:
|
||||
to-regex-range: 5.0.1
|
||||
|
@ -878,6 +1252,11 @@ snapshots:
|
|||
|
||||
flat@5.0.2: {}
|
||||
|
||||
fluent-ffmpeg@2.1.3:
|
||||
dependencies:
|
||||
async: 0.2.10
|
||||
which: 1.3.1
|
||||
|
||||
fs.realpath@1.0.0: {}
|
||||
|
||||
fsevents@2.3.3:
|
||||
|
@ -887,7 +1266,9 @@ snapshots:
|
|||
|
||||
get-func-name@2.0.2: {}
|
||||
|
||||
get-tsconfig@4.7.6:
|
||||
get-stream@8.0.1: {}
|
||||
|
||||
get-tsconfig@4.8.0:
|
||||
dependencies:
|
||||
resolve-pkg-maps: 1.0.0
|
||||
|
||||
|
@ -907,6 +1288,8 @@ snapshots:
|
|||
|
||||
he@1.2.0: {}
|
||||
|
||||
human-signals@5.0.0: {}
|
||||
|
||||
inflight@1.0.6:
|
||||
dependencies:
|
||||
once: 1.4.0
|
||||
|
@ -914,6 +1297,8 @@ snapshots:
|
|||
|
||||
inherits@2.0.4: {}
|
||||
|
||||
is-arrayish@0.3.2: {}
|
||||
|
||||
is-binary-path@2.1.0:
|
||||
dependencies:
|
||||
binary-extensions: 2.3.0
|
||||
|
@ -926,12 +1311,18 @@ snapshots:
|
|||
dependencies:
|
||||
is-extglob: 2.1.1
|
||||
|
||||
is-network-error@1.1.0: {}
|
||||
|
||||
is-number@7.0.0: {}
|
||||
|
||||
is-plain-obj@2.1.0: {}
|
||||
|
||||
is-stream@3.0.0: {}
|
||||
|
||||
is-unicode-supported@0.1.0: {}
|
||||
|
||||
isexe@2.0.0: {}
|
||||
|
||||
js-yaml@4.1.0:
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
|
@ -949,8 +1340,14 @@ snapshots:
|
|||
dependencies:
|
||||
get-func-name: 2.0.2
|
||||
|
||||
luxon@1.28.1: {}
|
||||
|
||||
make-error@1.3.6: {}
|
||||
|
||||
merge-stream@2.0.0: {}
|
||||
|
||||
mimic-fn@4.0.0: {}
|
||||
|
||||
minimatch@5.1.6:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
|
@ -984,10 +1381,18 @@ snapshots:
|
|||
|
||||
normalize-path@3.0.0: {}
|
||||
|
||||
npm-run-path@5.3.0:
|
||||
dependencies:
|
||||
path-key: 4.0.0
|
||||
|
||||
once@1.4.0:
|
||||
dependencies:
|
||||
wrappy: 1.0.2
|
||||
|
||||
onetime@6.0.0:
|
||||
dependencies:
|
||||
mimic-fn: 4.0.0
|
||||
|
||||
p-limit@3.1.0:
|
||||
dependencies:
|
||||
yocto-queue: 0.1.0
|
||||
|
@ -996,17 +1401,36 @@ snapshots:
|
|||
dependencies:
|
||||
p-limit: 3.1.0
|
||||
|
||||
p-retry@5.1.2:
|
||||
p-retry@6.2.0:
|
||||
dependencies:
|
||||
'@types/retry': 0.12.1
|
||||
'@types/retry': 0.12.2
|
||||
is-network-error: 1.1.0
|
||||
retry: 0.13.1
|
||||
|
||||
path-exists@4.0.0: {}
|
||||
|
||||
path-key@3.1.1: {}
|
||||
|
||||
path-key@4.0.0: {}
|
||||
|
||||
pathval@2.0.0: {}
|
||||
|
||||
picomatch@2.3.1: {}
|
||||
|
||||
prevvy@8.0.1:
|
||||
dependencies:
|
||||
'@types/debug': 4.1.12
|
||||
'@types/fluent-ffmpeg': 2.1.26
|
||||
'@types/luxon': 3.4.2
|
||||
'@types/node': 20.16.3
|
||||
debug: 4.3.6(supports-color@8.1.1)
|
||||
execa: 8.0.1
|
||||
fluent-ffmpeg: 2.1.3
|
||||
luxon: 1.28.1
|
||||
typescript: 5.5.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
randombytes@2.1.0:
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
|
@ -1023,10 +1447,50 @@ snapshots:
|
|||
|
||||
safe-buffer@5.2.1: {}
|
||||
|
||||
semver@7.6.3: {}
|
||||
|
||||
serialize-javascript@6.0.2:
|
||||
dependencies:
|
||||
randombytes: 2.1.0
|
||||
|
||||
sharp@0.33.5:
|
||||
dependencies:
|
||||
color: 4.2.3
|
||||
detect-libc: 2.0.3
|
||||
semver: 7.6.3
|
||||
optionalDependencies:
|
||||
'@img/sharp-darwin-arm64': 0.33.5
|
||||
'@img/sharp-darwin-x64': 0.33.5
|
||||
'@img/sharp-libvips-darwin-arm64': 1.0.4
|
||||
'@img/sharp-libvips-darwin-x64': 1.0.4
|
||||
'@img/sharp-libvips-linux-arm': 1.0.5
|
||||
'@img/sharp-libvips-linux-arm64': 1.0.4
|
||||
'@img/sharp-libvips-linux-s390x': 1.0.4
|
||||
'@img/sharp-libvips-linux-x64': 1.0.4
|
||||
'@img/sharp-libvips-linuxmusl-arm64': 1.0.4
|
||||
'@img/sharp-libvips-linuxmusl-x64': 1.0.4
|
||||
'@img/sharp-linux-arm': 0.33.5
|
||||
'@img/sharp-linux-arm64': 0.33.5
|
||||
'@img/sharp-linux-s390x': 0.33.5
|
||||
'@img/sharp-linux-x64': 0.33.5
|
||||
'@img/sharp-linuxmusl-arm64': 0.33.5
|
||||
'@img/sharp-linuxmusl-x64': 0.33.5
|
||||
'@img/sharp-wasm32': 0.33.5
|
||||
'@img/sharp-win32-ia32': 0.33.5
|
||||
'@img/sharp-win32-x64': 0.33.5
|
||||
|
||||
shebang-command@2.0.0:
|
||||
dependencies:
|
||||
shebang-regex: 3.0.0
|
||||
|
||||
shebang-regex@3.0.0: {}
|
||||
|
||||
signal-exit@4.1.0: {}
|
||||
|
||||
simple-swizzle@0.2.2:
|
||||
dependencies:
|
||||
is-arrayish: 0.3.2
|
||||
|
||||
slug@9.1.0: {}
|
||||
|
||||
string-width@4.2.3:
|
||||
|
@ -1039,6 +1503,8 @@ snapshots:
|
|||
dependencies:
|
||||
ansi-regex: 5.0.1
|
||||
|
||||
strip-final-newline@3.0.0: {}
|
||||
|
||||
strip-json-comments@3.1.1: {}
|
||||
|
||||
supports-color@7.2.0:
|
||||
|
@ -1053,14 +1519,14 @@ snapshots:
|
|||
dependencies:
|
||||
is-number: 7.0.0
|
||||
|
||||
ts-node@10.9.2(@types/node@20.16.1)(typescript@5.5.4):
|
||||
ts-node@10.9.2(@types/node@22.5.2)(typescript@5.5.4):
|
||||
dependencies:
|
||||
'@cspotcode/source-map-support': 0.8.1
|
||||
'@tsconfig/node10': 1.0.11
|
||||
'@tsconfig/node12': 1.0.11
|
||||
'@tsconfig/node14': 1.0.3
|
||||
'@tsconfig/node16': 1.0.4
|
||||
'@types/node': 20.16.1
|
||||
'@types/node': 22.5.2
|
||||
acorn: 8.12.1
|
||||
acorn-walk: 8.3.3
|
||||
arg: 4.1.3
|
||||
|
@ -1071,10 +1537,13 @@ snapshots:
|
|||
v8-compile-cache-lib: 3.0.1
|
||||
yn: 3.1.1
|
||||
|
||||
tsx@4.17.0:
|
||||
tslib@2.7.0:
|
||||
optional: true
|
||||
|
||||
tsx@4.19.0:
|
||||
dependencies:
|
||||
esbuild: 0.23.1
|
||||
get-tsconfig: 4.7.6
|
||||
get-tsconfig: 4.8.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
|
||||
|
@ -1084,6 +1553,14 @@ snapshots:
|
|||
|
||||
v8-compile-cache-lib@3.0.1: {}
|
||||
|
||||
which@1.3.1:
|
||||
dependencies:
|
||||
isexe: 2.0.0
|
||||
|
||||
which@2.0.2:
|
||||
dependencies:
|
||||
isexe: 2.0.0
|
||||
|
||||
workerpool@6.5.1: {}
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
|
@ -1108,7 +1585,7 @@ snapshots:
|
|||
yargs@16.2.0:
|
||||
dependencies:
|
||||
cliui: 7.0.4
|
||||
escalade: 3.1.2
|
||||
escalade: 3.2.0
|
||||
get-caller-file: 2.0.5
|
||||
require-directory: 2.1.1
|
||||
string-width: 4.2.3
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
import { getTmpFile, download, getPackageVersion } from './file.ts'
|
||||
import { expect } from 'chai'
|
||||
import { describe } from 'mocha'
|
||||
import { dirname, basename, join, isAbsolute } from 'node:path';
|
||||
import { fileURLToPath } from 'url';
|
||||
export const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
describe('file', function () {
|
||||
describe('integration', function () {
|
||||
describe('download', function () {
|
||||
it('should get the file', async function () {
|
||||
const file = await download({ url: 'https://futureporn-b2.b-cdn.net/sample.webp' })
|
||||
expect(file).to.match(/\/tmp\/.*sample\.webp$/)
|
||||
})
|
||||
})
|
||||
})
|
||||
describe('unit', function () {
|
||||
describe('getTmpFile', function () {
|
||||
it('should give a /tmp/<random>_<basename> path', function () {
|
||||
expect(getTmpFile('my-cool-image.webp')).to.match(/\/tmp\/.*_my-cool-image\.webp/)
|
||||
expect(getTmpFile('video.mp4')).to.match(/\/tmp\/.*_video\.mp4/)
|
||||
})
|
||||
})
|
||||
describe('getPackageVersion', function () {
|
||||
it('should get the version from package.json', function () {
|
||||
expect(getPackageVersion(join(__dirname, '../package.json'))).to.match(/\d+\.\d+\.\d+/)
|
||||
})
|
||||
it('should handle a relative path', function () {
|
||||
expect(getPackageVersion('../package.json')).to.match(/\d+\.\d+\.\d+/)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -1,10 +1,8 @@
|
|||
import slug from 'slug';
|
||||
import os from 'node:os';
|
||||
import fs from 'node:fs';
|
||||
import { createId } from '@paralleldrive/cuid2';
|
||||
import { Readable } from 'stream';
|
||||
import { finished } from 'stream/promises';
|
||||
import pRetry from 'p-retry';
|
||||
import { dirname, basename, join, isAbsolute } from 'node:path';
|
||||
import { fileURLToPath } from 'url';
|
||||
export const __filename = fileURLToPath(import.meta.url);
|
||||
|
@ -27,14 +25,6 @@ export function getPackageVersion(packageJsonPath: string): string {
|
|||
}
|
||||
}
|
||||
|
||||
export function fpSlugify(str: string): string {
|
||||
return slug(str, {
|
||||
replacement: '-',
|
||||
lower: true,
|
||||
locale: 'en',
|
||||
trim: true,
|
||||
});
|
||||
}
|
||||
|
||||
export function getTmpFile(str: string): string {
|
||||
return join(os.tmpdir(), `${createId()}_${basename(str)}`);
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
@ -0,0 +1,39 @@
|
|||
|
||||
import { getProminentColor, rgbToHex, getStoryboard } from './image.ts'
|
||||
import { expect } from 'chai'
|
||||
import { describe } from 'mocha'
|
||||
import { dirname, basename, join, isAbsolute } from 'node:path';
|
||||
import { fileURLToPath } from 'url';
|
||||
export const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
describe('image', function () {
|
||||
describe('unit', function () {
|
||||
describe('getProminentColor', function () {
|
||||
it('should get a {String} hex code color', async function () {
|
||||
const color = await getProminentColor(join(import.meta.dirname, './fixtures/sample.webp'))
|
||||
expect(color).to.equal('#0878a8')
|
||||
})
|
||||
})
|
||||
describe('rgbToHex', function () {
|
||||
it('should convert color to hex {String} hexidecimal code', function () {
|
||||
const mulberry = [255, 87, 51] as const
|
||||
const screaminGreen = [77, 255, 106] as const
|
||||
const amaranth = [227, 64, 81] as const
|
||||
expect(rgbToHex(...mulberry)).to.equal('#ff5733')
|
||||
expect(rgbToHex(...screaminGreen)).to.equal('#4dff6a')
|
||||
expect(rgbToHex(...amaranth)).to.equal('#e34051')
|
||||
})
|
||||
})
|
||||
})
|
||||
describe('integration', function () {
|
||||
describe('getStoryboard', function () {
|
||||
this.timeout(1000*60*15)
|
||||
it('should accept a URL and return a path to image on disk', async function () {
|
||||
const url = 'https://futureporn-b2.b-cdn.net/projektmelody-chaturbate-2024-08-31.mp4'
|
||||
const imagePath = await getStoryboard(url)
|
||||
expect(imagePath).to.match(/\.png/)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -1,8 +1,7 @@
|
|||
// import ColorThief from 'colorthief';
|
||||
import sharp from 'sharp';
|
||||
import Prevvy from 'prevvy';
|
||||
import path from 'path';
|
||||
import { getTmpFile } from '@futureporn/utils';
|
||||
import { getTmpFile } from './file.ts';
|
||||
|
||||
export async function getProminentColor(imageFile: string): Promise<string> {
|
||||
const { dominant } = await sharp(imageFile).stats();
|
|
@ -1,34 +0,0 @@
|
|||
import { fpSlugify, getTmpFile, download, getPackageVersion, __dirname } from './index.ts'
|
||||
import { expect } from 'chai'
|
||||
import { describe } from 'mocha'
|
||||
import { join } from 'path'
|
||||
|
||||
describe('utils', function () {
|
||||
describe('fpSlugify', function () {
|
||||
it('should remove all capitalization and uppercase and spaces and special characters', function () {
|
||||
expect(fpSlugify('ProjektMelody')).to.equal('projektmelody')
|
||||
expect(fpSlugify('CJ_Clippy')).to.equal('cjclippy')
|
||||
})
|
||||
})
|
||||
describe('getTmpFile', function () {
|
||||
it('should give a /tmp/<random>_<basename> path', function () {
|
||||
expect(getTmpFile('my-cool-image.webp')).to.match(/\/tmp\/.*_my-cool-image\.webp/)
|
||||
expect(getTmpFile('video.mp4')).to.match(/\/tmp\/.*_video\.mp4/)
|
||||
})
|
||||
})
|
||||
// disabled because it's an integration test, slow
|
||||
xdescribe('download', function () {
|
||||
it('should get the file', async function () {
|
||||
const file = await download({ url: 'https://futureporn-b2.b-cdn.net/sample.webp' })
|
||||
expect(file).to.match(/\/tmp\/.*sample\.webp$/)
|
||||
})
|
||||
})
|
||||
describe('getPackageVersion', function () {
|
||||
it('should get the version from package.json', function () {
|
||||
expect(getPackageVersion(join(__dirname, '../package.json'))).to.match(/\d+\.\d+\.\d+/)
|
||||
})
|
||||
it('should handle a relative path', function () {
|
||||
expect(getPackageVersion('../package.json')).to.match(/\d+\.\d+\.\d+/)
|
||||
})
|
||||
})
|
||||
})
|
|
@ -0,0 +1,13 @@
|
|||
import { fpSlugify } from './name.ts'
|
||||
import { expect } from 'chai'
|
||||
|
||||
describe('name', function () {
|
||||
describe('unit', function () {
|
||||
describe('fpSlugify', function () {
|
||||
it('should remove all capitalization and uppercase and spaces and special characters', function () {
|
||||
expect(fpSlugify('ProjektMelody')).to.equal('projektmelody')
|
||||
expect(fpSlugify('CJ_Clippy')).to.equal('cjclippy')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
|
@ -0,0 +1,10 @@
|
|||
import slug from 'slug';
|
||||
|
||||
export function fpSlugify(str: string): string {
|
||||
return slug(str, {
|
||||
replacement: '-',
|
||||
lower: true,
|
||||
locale: 'en',
|
||||
trim: true,
|
||||
});
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
import { expect } from 'chai'
|
||||
|
||||
describe('video', function () {
|
||||
describe('unit', function () {
|
||||
xdescribe('remux', function () {
|
||||
})
|
||||
})
|
||||
})
|
|
@ -0,0 +1,15 @@
|
|||
import { promisify } from "util"
|
||||
import { execFile } from "child_process"
|
||||
|
||||
|
||||
export async function remux(inputVideoPath: string, outputVideoPath: string): Promise<void> {
|
||||
console.log(`remuxing video ${inputVideoPath} and ouputting to ${outputVideoPath}.`)
|
||||
const execFileP = promisify(execFile)
|
||||
const { stdout, stderr } = await execFileP('ffmpeg', [
|
||||
'-i', inputVideoPath,
|
||||
'-c', 'copy',
|
||||
outputVideoPath
|
||||
])
|
||||
console.log(`stdout=${stdout}`)
|
||||
console.log(`stderr=${stderr}`)
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"name": "video",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Warn: no test specified\" && exit 0",
|
||||
"clean": "rm -rf dist",
|
||||
"superclean": "rm -rf node_modules && rm -rf pnpm-lock.yaml && rm -rf dist"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "Unlicense"
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
lockfileVersion: '9.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
importers:
|
||||
|
||||
.: {}
|
|
@ -18,8 +18,8 @@ importers:
|
|||
|
||||
packages:
|
||||
|
||||
'@babel/runtime@7.25.4':
|
||||
resolution: {integrity: sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==}
|
||||
'@babel/runtime@7.25.6':
|
||||
resolution: {integrity: sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
ansi-regex@5.0.1:
|
||||
|
@ -57,8 +57,8 @@ packages:
|
|||
emoji-regex@8.0.0:
|
||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||
|
||||
escalade@3.1.2:
|
||||
resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
|
||||
escalade@3.2.0:
|
||||
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
get-caller-file@2.0.5:
|
||||
|
@ -137,7 +137,7 @@ packages:
|
|||
|
||||
snapshots:
|
||||
|
||||
'@babel/runtime@7.25.4':
|
||||
'@babel/runtime@7.25.6':
|
||||
dependencies:
|
||||
regenerator-runtime: 0.14.1
|
||||
|
||||
|
@ -178,11 +178,11 @@ snapshots:
|
|||
|
||||
date-fns@2.30.0:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.25.4
|
||||
'@babel/runtime': 7.25.6
|
||||
|
||||
emoji-regex@8.0.0: {}
|
||||
|
||||
escalade@3.1.2: {}
|
||||
escalade@3.2.0: {}
|
||||
|
||||
get-caller-file@2.0.5: {}
|
||||
|
||||
|
@ -241,7 +241,7 @@ snapshots:
|
|||
yargs@17.7.2:
|
||||
dependencies:
|
||||
cliui: 8.0.1
|
||||
escalade: 3.1.2
|
||||
escalade: 3.2.0
|
||||
get-caller-file: 2.0.5
|
||||
require-directory: 2.1.1
|
||||
string-width: 4.2.3
|
||||
|
|
|
@ -23,33 +23,33 @@
|
|||
"author": "@CJ_Clippy",
|
||||
"license": "Unlicense",
|
||||
"dependencies": {
|
||||
"@discordeno/bot": "19.0.0-next.746f0a9",
|
||||
"@discordeno/bot": "19.0.0-next.b1bfe94",
|
||||
"@discordeno/rest": "19.0.0-next.b3a8c86",
|
||||
"@paralleldrive/cuid2": "^2.2.2",
|
||||
"@types/node": "^22.2.0",
|
||||
"@types/node": "^22.5.2",
|
||||
"@types/qs": "^6.9.15",
|
||||
"date-fns": "^3.6.0",
|
||||
"dd-cache-proxy": "^2.1.1",
|
||||
"dd-cache-proxy": "^2.1.2",
|
||||
"discordeno": "19.0.0-next.b3a8c86",
|
||||
"dotenv": "^16.4.5",
|
||||
"graphile-config": "0.0.1-beta.9",
|
||||
"graphile-worker": "^0.16.6",
|
||||
"node-fetch": "^3.3.2",
|
||||
"p-retry": "^5.1.2",
|
||||
"pg": "8.8.0",
|
||||
"p-retry": "^6.2.0",
|
||||
"pg": "8.12.0",
|
||||
"pretty-bytes": "^6.1.1",
|
||||
"qs": "^6.13.0",
|
||||
"rate-limiter-flexible": "^5.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@futureporn/types": "workspace:^",
|
||||
"@types/chai": "^4.3.16",
|
||||
"@types/chai": "^4.3.19",
|
||||
"@types/mocha": "^10.0.7",
|
||||
"chai": "^5.1.1",
|
||||
"mocha": "^10.7.3",
|
||||
"nodemon": "^3.1.4",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsx": "^4.17.0",
|
||||
"tsx": "^4.19.0",
|
||||
"typescript": "^5.5.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@ importers:
|
|||
.:
|
||||
dependencies:
|
||||
'@discordeno/bot':
|
||||
specifier: 19.0.0-next.746f0a9
|
||||
version: 19.0.0-next.746f0a9
|
||||
specifier: 19.0.0-next.b1bfe94
|
||||
version: 19.0.0-next.b1bfe94
|
||||
'@discordeno/rest':
|
||||
specifier: 19.0.0-next.b3a8c86
|
||||
version: 19.0.0-next.b3a8c86
|
||||
|
@ -18,8 +18,8 @@ importers:
|
|||
specifier: ^2.2.2
|
||||
version: 2.2.2
|
||||
'@types/node':
|
||||
specifier: ^22.2.0
|
||||
version: 22.5.0
|
||||
specifier: ^22.5.2
|
||||
version: 22.5.2
|
||||
'@types/qs':
|
||||
specifier: ^6.9.15
|
||||
version: 6.9.15
|
||||
|
@ -27,8 +27,8 @@ importers:
|
|||
specifier: ^3.6.0
|
||||
version: 3.6.0
|
||||
dd-cache-proxy:
|
||||
specifier: ^2.1.1
|
||||
version: 2.1.2(@discordeno/bot@19.0.0-next.746f0a9)
|
||||
specifier: ^2.1.2
|
||||
version: 2.1.2(@discordeno/bot@19.0.0-next.b1bfe94)
|
||||
discordeno:
|
||||
specifier: 19.0.0-next.b3a8c86
|
||||
version: 19.0.0-next.b3a8c86
|
||||
|
@ -45,11 +45,11 @@ importers:
|
|||
specifier: ^3.3.2
|
||||
version: 3.3.2
|
||||
p-retry:
|
||||
specifier: ^5.1.2
|
||||
version: 5.1.2
|
||||
specifier: ^6.2.0
|
||||
version: 6.2.0
|
||||
pg:
|
||||
specifier: 8.8.0
|
||||
version: 8.8.0
|
||||
specifier: 8.12.0
|
||||
version: 8.12.0
|
||||
pretty-bytes:
|
||||
specifier: ^6.1.1
|
||||
version: 6.1.1
|
||||
|
@ -64,8 +64,8 @@ importers:
|
|||
specifier: workspace:^
|
||||
version: link:../../packages/types
|
||||
'@types/chai':
|
||||
specifier: ^4.3.16
|
||||
version: 4.3.17
|
||||
specifier: ^4.3.19
|
||||
version: 4.3.19
|
||||
'@types/mocha':
|
||||
specifier: ^10.0.7
|
||||
version: 10.0.7
|
||||
|
@ -80,50 +80,14 @@ importers:
|
|||
version: 3.1.4
|
||||
ts-node:
|
||||
specifier: ^10.9.2
|
||||
version: 10.9.2(@types/node@22.5.0)(typescript@5.5.4)
|
||||
version: 10.9.2(@types/node@22.5.2)(typescript@5.5.4)
|
||||
tsx:
|
||||
specifier: ^4.17.0
|
||||
version: 4.17.0
|
||||
specifier: ^4.19.0
|
||||
version: 4.19.0
|
||||
typescript:
|
||||
specifier: ^5.5.4
|
||||
version: 5.5.4
|
||||
|
||||
../..: {}
|
||||
|
||||
../../packages/image: {}
|
||||
|
||||
../../packages/infra: {}
|
||||
|
||||
../../packages/meal: {}
|
||||
|
||||
../../packages/old: {}
|
||||
|
||||
../../packages/storage: {}
|
||||
|
||||
../../packages/taco: {}
|
||||
|
||||
../../packages/types: {}
|
||||
|
||||
../../packages/utils: {}
|
||||
|
||||
../../packages/video: {}
|
||||
|
||||
../capture: {}
|
||||
|
||||
../factory: {}
|
||||
|
||||
../mailbox: {}
|
||||
|
||||
../migrations: {}
|
||||
|
||||
../next: {}
|
||||
|
||||
../scout: {}
|
||||
|
||||
../strapi: {}
|
||||
|
||||
../uppy: {}
|
||||
|
||||
packages:
|
||||
|
||||
'@babel/code-frame@7.24.7':
|
||||
|
@ -142,32 +106,32 @@ packages:
|
|||
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@discordeno/bot@19.0.0-next.746f0a9':
|
||||
resolution: {integrity: sha512-M0BqdbGcJSHr7Nmxw/okFtkKZ9mMM0yUHBbB0XApxFxBRt68I1JhVbdFMwDkVAutargEr8BVDSt5SqUVpMnbrQ==}
|
||||
'@discordeno/bot@19.0.0-next.b1bfe94':
|
||||
resolution: {integrity: sha512-ZaPDaPM6tuxpRZCyuNB2rzqz2WYHH20IQdutu87jffW2dV26D3Nw8SJCE1LNdXdu9akes3VMXolkNsLJ5MW2Hw==}
|
||||
|
||||
'@discordeno/bot@19.0.0-next.b3a8c86':
|
||||
resolution: {integrity: sha512-Jm7sEmxR0MyK3kwe8CVHDQfAXpbkkPLER2nGuS2nn2e/0AXQKCCgJRMNmorJ+ZzcSw+slrw4hHkVZMBv7JML9Q==}
|
||||
|
||||
'@discordeno/gateway@19.0.0-next.746f0a9':
|
||||
resolution: {integrity: sha512-IvXISmDVC8bGUreR/wo4hYoH4p8w5YanDDMpdO+ex6DTlsA2AgvpzzIHeshfOZNAupdr4spp4TDxziXfq1skhQ==}
|
||||
'@discordeno/gateway@19.0.0-next.b1bfe94':
|
||||
resolution: {integrity: sha512-rNkcCua4Inx8NkuCjbuRBAAg+AIg1qYb24Fq6/Y2+1s+iO0VSQ/ZK8PRNbI2gSpAtAbfndvxA9kyU1ggwwLjNw==}
|
||||
|
||||
'@discordeno/gateway@19.0.0-next.b3a8c86':
|
||||
resolution: {integrity: sha512-FGQvHcJFCyC4WCdgvRo3vAMoyvDpTkbHN4DZlEDNhN6uBMsWsd1xbjWPsJTdWGVUvHQd4+5HOv44wPhO02jytg==}
|
||||
|
||||
'@discordeno/rest@19.0.0-next.746f0a9':
|
||||
resolution: {integrity: sha512-qM0d/MFhzC2TWDclwiVL4Tt/37C26gjCUgb0x9mwnQsetJvsYmd+nzQI6SCkzKjsn/esWCtjSSHFQ7z6bdURpw==}
|
||||
'@discordeno/rest@19.0.0-next.b1bfe94':
|
||||
resolution: {integrity: sha512-lLeP3hmMM0GFsO+VA3f9EKOwfIo1HvG1hudtlC1Er6BFWgArpz0/VizHbOyOr5SzZuzrQyfcBJJfEhC+48TsRg==}
|
||||
|
||||
'@discordeno/rest@19.0.0-next.b3a8c86':
|
||||
resolution: {integrity: sha512-nhhHSzibxOwxFAckgcuU8nGj+AGo3IRb1qiCcTE4gQStjqmV3ZewoVRzaRGgoY4t5ld5oeDODplXY5tloobkiw==}
|
||||
|
||||
'@discordeno/types@19.0.0-next.746f0a9':
|
||||
resolution: {integrity: sha512-v/nG0vIFukJzFqAzABat2eGV3a7jTDQzbPkj1yoWaFfcB6pxlF44XJ4nsLLsvWj7oRH8eR97yMa2BT697Rs5JA==}
|
||||
'@discordeno/types@19.0.0-next.b1bfe94':
|
||||
resolution: {integrity: sha512-X1MmdPFMyzjxFEANEPrrBjdJDJBAz4RTa1vpVlMp46C3dPqTwjMwijaPhPgPnFiSwt01lJ8WaFDpMvfqOwpQNg==}
|
||||
|
||||
'@discordeno/types@19.0.0-next.b3a8c86':
|
||||
resolution: {integrity: sha512-1uUOpfBN3a8zDYOyL61qvWhG+NL4KMjcun7XFg7CB6wjGubUv4Uc2QXKG7SkSfNmtYzxetrrx1kyoSxkbEHLOw==}
|
||||
|
||||
'@discordeno/utils@19.0.0-next.746f0a9':
|
||||
resolution: {integrity: sha512-UY5GataakuY0yc4SN5qJLexUbTc5y293G3gNAWSaOjaZivEytcdxD4xgeqjNj9c4eN57B3Lfzus6tFZHXwXNOA==}
|
||||
'@discordeno/utils@19.0.0-next.b1bfe94':
|
||||
resolution: {integrity: sha512-Y+j3G83vCVXiNSEQlFR9WWJ6GZhvBmIfFjb03zFcmHa20nHExILJJBEyDpS+ptziEyF7jB+2hNw5I/SKn8Zm2w==}
|
||||
|
||||
'@discordeno/utils@19.0.0-next.b3a8c86':
|
||||
resolution: {integrity: sha512-W4SDymUvevihQZry9hB4lzCUNSz5QwqAzdT+3VKswjARgmQQnOjZdJ1w9rX/xoMB5FgS8Vhk6er4ABULIwPi6g==}
|
||||
|
@ -329,9 +293,9 @@ packages:
|
|||
'@jridgewell/trace-mapping@0.3.9':
|
||||
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
|
||||
|
||||
'@noble/hashes@1.4.0':
|
||||
resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==}
|
||||
engines: {node: '>= 16'}
|
||||
'@noble/hashes@1.5.0':
|
||||
resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==}
|
||||
engines: {node: ^14.21.3 || >=16}
|
||||
|
||||
'@paralleldrive/cuid2@2.2.2':
|
||||
resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==}
|
||||
|
@ -348,8 +312,8 @@ packages:
|
|||
'@tsconfig/node16@1.0.4':
|
||||
resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
|
||||
|
||||
'@types/chai@4.3.17':
|
||||
resolution: {integrity: sha512-zmZ21EWzR71B4Sscphjief5djsLre50M6lI622OSySTmn9DB3j+C3kWroHfBQWXbOBwbgg/M8CG/hUxDLIloow==}
|
||||
'@types/chai@4.3.19':
|
||||
resolution: {integrity: sha512-2hHHvQBVE2FiSK4eN0Br6snX9MtolHaTo/batnLjlGRhoQzlCL61iVpxoqO7SfFyOw+P/pwv+0zNHzKoGWz9Cw==}
|
||||
|
||||
'@types/debug@4.1.12':
|
||||
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
||||
|
@ -363,20 +327,20 @@ packages:
|
|||
'@types/ms@0.7.34':
|
||||
resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==}
|
||||
|
||||
'@types/node@20.16.1':
|
||||
resolution: {integrity: sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==}
|
||||
'@types/node@20.16.3':
|
||||
resolution: {integrity: sha512-/wdGiWRkMOm53gAsSyFMXFZHbVg7C6CbkrzHNpaHoYfsUWPg7m6ZRKtvQjgvQ9i8WT540a3ydRlRQbxjY30XxQ==}
|
||||
|
||||
'@types/node@22.5.0':
|
||||
resolution: {integrity: sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==}
|
||||
'@types/node@22.5.2':
|
||||
resolution: {integrity: sha512-acJsPTEqYqulZS/Yp/S3GgeE6GZ0qYODUR8aVr/DkhHQ8l9nd4j5x1/ZJy9/gHrRlFMqkO6i0I3E27Alu4jjPg==}
|
||||
|
||||
'@types/pg@8.11.6':
|
||||
resolution: {integrity: sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==}
|
||||
'@types/pg@8.11.8':
|
||||
resolution: {integrity: sha512-IqpCf8/569txXN/HoP5i1LjXfKZWL76Yr2R77xgeIICUbAYHeoaEZFhYHo2uDftecLWrTJUq63JvQu8q3lnDyA==}
|
||||
|
||||
'@types/qs@6.9.15':
|
||||
resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==}
|
||||
|
||||
'@types/retry@0.12.1':
|
||||
resolution: {integrity: sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==}
|
||||
'@types/retry@0.12.2':
|
||||
resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==}
|
||||
|
||||
'@types/semver@7.5.8':
|
||||
resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
|
||||
|
@ -440,10 +404,6 @@ packages:
|
|||
browser-stdout@1.3.1:
|
||||
resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==}
|
||||
|
||||
buffer-writer@2.0.0:
|
||||
resolution: {integrity: sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
call-bind@1.0.7:
|
||||
resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
@ -583,8 +543,8 @@ packages:
|
|||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
escalade@3.1.2:
|
||||
resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
|
||||
escalade@3.2.0:
|
||||
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
escape-string-regexp@1.0.5:
|
||||
|
@ -641,8 +601,8 @@ packages:
|
|||
resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
get-tsconfig@4.7.6:
|
||||
resolution: {integrity: sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==}
|
||||
get-tsconfig@4.8.0:
|
||||
resolution: {integrity: sha512-Pgba6TExTZ0FJAn1qkJAjIeKoDJ3CsI2ChuLohJnZl/tTU8MVrq3b+2t5UOPfRa4RMsorClBjJALkJUMjG1PAw==}
|
||||
|
||||
glob-parent@5.1.2:
|
||||
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
||||
|
@ -729,6 +689,10 @@ packages:
|
|||
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
is-network-error@1.1.0:
|
||||
resolution: {integrity: sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
is-number@7.0.0:
|
||||
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
|
||||
engines: {node: '>=0.12.0'}
|
||||
|
@ -838,12 +802,9 @@ packages:
|
|||
resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
|
||||
p-retry@5.1.2:
|
||||
resolution: {integrity: sha512-couX95waDu98NfNZV+i/iLt+fdVxmI7CbrrdC2uDWfPdUAApyxT4wmDlyOtR5KtTDmkDO0zDScDjDou9YHhd9g==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
|
||||
packet-reader@1.0.0:
|
||||
resolution: {integrity: sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==}
|
||||
p-retry@6.2.0:
|
||||
resolution: {integrity: sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==}
|
||||
engines: {node: '>=16.17'}
|
||||
|
||||
parent-module@1.0.1:
|
||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
||||
|
@ -908,20 +869,11 @@ packages:
|
|||
pg-native:
|
||||
optional: true
|
||||
|
||||
pg@8.8.0:
|
||||
resolution: {integrity: sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==}
|
||||
engines: {node: '>= 8.0.0'}
|
||||
peerDependencies:
|
||||
pg-native: '>=3.0.1'
|
||||
peerDependenciesMeta:
|
||||
pg-native:
|
||||
optional: true
|
||||
|
||||
pgpass@1.0.5:
|
||||
resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==}
|
||||
|
||||
picocolors@1.0.1:
|
||||
resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
|
||||
picocolors@1.1.0:
|
||||
resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==}
|
||||
|
||||
picomatch@2.3.1:
|
||||
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
|
||||
|
@ -1074,8 +1026,8 @@ packages:
|
|||
tslib@2.7.0:
|
||||
resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==}
|
||||
|
||||
tsx@4.17.0:
|
||||
resolution: {integrity: sha512-eN4mnDA5UMKDt4YZixo9tBioibaMBpoxBkD+rIPAjVmYERSG0/dWEY1CEFuV89CgASlKL499q8AhmkMnnjtOJg==}
|
||||
tsx@4.19.0:
|
||||
resolution: {integrity: sha512-bV30kM7bsLZKZIOCHeMNVMJ32/LuJzLVajkQI/qf92J2Qr08ueLQvW00PUZGiuLPP760UINwupgUj8qrSCPUKg==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
hasBin: true
|
||||
|
||||
|
@ -1168,7 +1120,7 @@ snapshots:
|
|||
'@babel/code-frame@7.24.7':
|
||||
dependencies:
|
||||
'@babel/highlight': 7.24.7
|
||||
picocolors: 1.0.1
|
||||
picocolors: 1.1.0
|
||||
|
||||
'@babel/helper-validator-identifier@7.24.7': {}
|
||||
|
||||
|
@ -1177,18 +1129,18 @@ snapshots:
|
|||
'@babel/helper-validator-identifier': 7.24.7
|
||||
chalk: 2.4.2
|
||||
js-tokens: 4.0.0
|
||||
picocolors: 1.0.1
|
||||
picocolors: 1.1.0
|
||||
|
||||
'@cspotcode/source-map-support@0.8.1':
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.9
|
||||
|
||||
'@discordeno/bot@19.0.0-next.746f0a9':
|
||||
'@discordeno/bot@19.0.0-next.b1bfe94':
|
||||
dependencies:
|
||||
'@discordeno/gateway': 19.0.0-next.746f0a9
|
||||
'@discordeno/rest': 19.0.0-next.746f0a9
|
||||
'@discordeno/types': 19.0.0-next.746f0a9
|
||||
'@discordeno/utils': 19.0.0-next.746f0a9
|
||||
'@discordeno/gateway': 19.0.0-next.b1bfe94
|
||||
'@discordeno/rest': 19.0.0-next.b1bfe94
|
||||
'@discordeno/types': 19.0.0-next.b1bfe94
|
||||
'@discordeno/utils': 19.0.0-next.b1bfe94
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
|
@ -1203,10 +1155,10 @@ snapshots:
|
|||
- bufferutil
|
||||
- utf-8-validate
|
||||
|
||||
'@discordeno/gateway@19.0.0-next.746f0a9':
|
||||
'@discordeno/gateway@19.0.0-next.b1bfe94':
|
||||
dependencies:
|
||||
'@discordeno/types': 19.0.0-next.746f0a9
|
||||
'@discordeno/utils': 19.0.0-next.746f0a9
|
||||
'@discordeno/types': 19.0.0-next.b1bfe94
|
||||
'@discordeno/utils': 19.0.0-next.b1bfe94
|
||||
ws: 8.18.0
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
|
@ -1221,23 +1173,23 @@ snapshots:
|
|||
- bufferutil
|
||||
- utf-8-validate
|
||||
|
||||
'@discordeno/rest@19.0.0-next.746f0a9':
|
||||
'@discordeno/rest@19.0.0-next.b1bfe94':
|
||||
dependencies:
|
||||
'@discordeno/types': 19.0.0-next.746f0a9
|
||||
'@discordeno/utils': 19.0.0-next.746f0a9
|
||||
'@discordeno/types': 19.0.0-next.b1bfe94
|
||||
'@discordeno/utils': 19.0.0-next.b1bfe94
|
||||
|
||||
'@discordeno/rest@19.0.0-next.b3a8c86':
|
||||
dependencies:
|
||||
'@discordeno/types': 19.0.0-next.b3a8c86
|
||||
'@discordeno/utils': 19.0.0-next.b3a8c86
|
||||
|
||||
'@discordeno/types@19.0.0-next.746f0a9': {}
|
||||
'@discordeno/types@19.0.0-next.b1bfe94': {}
|
||||
|
||||
'@discordeno/types@19.0.0-next.b3a8c86': {}
|
||||
|
||||
'@discordeno/utils@19.0.0-next.746f0a9':
|
||||
'@discordeno/utils@19.0.0-next.b1bfe94':
|
||||
dependencies:
|
||||
'@discordeno/types': 19.0.0-next.746f0a9
|
||||
'@discordeno/types': 19.0.0-next.b1bfe94
|
||||
|
||||
'@discordeno/utils@19.0.0-next.b3a8c86':
|
||||
dependencies:
|
||||
|
@ -1326,11 +1278,11 @@ snapshots:
|
|||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.5.0
|
||||
|
||||
'@noble/hashes@1.4.0': {}
|
||||
'@noble/hashes@1.5.0': {}
|
||||
|
||||
'@paralleldrive/cuid2@2.2.2':
|
||||
dependencies:
|
||||
'@noble/hashes': 1.4.0
|
||||
'@noble/hashes': 1.5.0
|
||||
|
||||
'@tsconfig/node10@1.0.11': {}
|
||||
|
||||
|
@ -1340,7 +1292,7 @@ snapshots:
|
|||
|
||||
'@tsconfig/node16@1.0.4': {}
|
||||
|
||||
'@types/chai@4.3.17': {}
|
||||
'@types/chai@4.3.19': {}
|
||||
|
||||
'@types/debug@4.1.12':
|
||||
dependencies:
|
||||
|
@ -1348,29 +1300,29 @@ snapshots:
|
|||
|
||||
'@types/interpret@1.1.3':
|
||||
dependencies:
|
||||
'@types/node': 22.5.0
|
||||
'@types/node': 22.5.2
|
||||
|
||||
'@types/mocha@10.0.7': {}
|
||||
|
||||
'@types/ms@0.7.34': {}
|
||||
|
||||
'@types/node@20.16.1':
|
||||
'@types/node@20.16.3':
|
||||
dependencies:
|
||||
undici-types: 6.19.8
|
||||
|
||||
'@types/node@22.5.0':
|
||||
'@types/node@22.5.2':
|
||||
dependencies:
|
||||
undici-types: 6.19.8
|
||||
|
||||
'@types/pg@8.11.6':
|
||||
'@types/pg@8.11.8':
|
||||
dependencies:
|
||||
'@types/node': 22.5.0
|
||||
'@types/node': 22.5.2
|
||||
pg-protocol: 1.6.1
|
||||
pg-types: 4.0.2
|
||||
|
||||
'@types/qs@6.9.15': {}
|
||||
|
||||
'@types/retry@0.12.1': {}
|
||||
'@types/retry@0.12.2': {}
|
||||
|
||||
'@types/semver@7.5.8': {}
|
||||
|
||||
|
@ -1422,8 +1374,6 @@ snapshots:
|
|||
|
||||
browser-stdout@1.3.1: {}
|
||||
|
||||
buffer-writer@2.0.0: {}
|
||||
|
||||
call-bind@1.0.7:
|
||||
dependencies:
|
||||
es-define-property: 1.0.0
|
||||
|
@ -1512,9 +1462,9 @@ snapshots:
|
|||
|
||||
date-fns@3.6.0: {}
|
||||
|
||||
dd-cache-proxy@2.1.2(@discordeno/bot@19.0.0-next.746f0a9):
|
||||
dd-cache-proxy@2.1.2(@discordeno/bot@19.0.0-next.b1bfe94):
|
||||
dependencies:
|
||||
'@discordeno/bot': 19.0.0-next.746f0a9
|
||||
'@discordeno/bot': 19.0.0-next.b1bfe94
|
||||
|
||||
debug@4.3.6:
|
||||
dependencies:
|
||||
|
@ -1601,7 +1551,7 @@ snapshots:
|
|||
'@esbuild/win32-ia32': 0.23.1
|
||||
'@esbuild/win32-x64': 0.23.1
|
||||
|
||||
escalade@3.1.2: {}
|
||||
escalade@3.2.0: {}
|
||||
|
||||
escape-string-regexp@1.0.5: {}
|
||||
|
||||
|
@ -1652,7 +1602,7 @@ snapshots:
|
|||
has-symbols: 1.0.3
|
||||
hasown: 2.0.2
|
||||
|
||||
get-tsconfig@4.7.6:
|
||||
get-tsconfig@4.8.0:
|
||||
dependencies:
|
||||
resolve-pkg-maps: 1.0.0
|
||||
|
||||
|
@ -1675,7 +1625,7 @@ snapshots:
|
|||
graphile-config@0.0.1-beta.9:
|
||||
dependencies:
|
||||
'@types/interpret': 1.1.3
|
||||
'@types/node': 20.16.1
|
||||
'@types/node': 20.16.3
|
||||
'@types/semver': 7.5.8
|
||||
chalk: 4.1.2
|
||||
debug: 4.3.6
|
||||
|
@ -1690,7 +1640,7 @@ snapshots:
|
|||
dependencies:
|
||||
'@graphile/logger': 0.2.0
|
||||
'@types/debug': 4.1.12
|
||||
'@types/pg': 8.11.6
|
||||
'@types/pg': 8.11.8
|
||||
cosmiconfig: 8.3.6(typescript@5.5.4)
|
||||
graphile-config: 0.0.1-beta.9
|
||||
json5: 2.2.3
|
||||
|
@ -1750,6 +1700,8 @@ snapshots:
|
|||
dependencies:
|
||||
is-extglob: 2.1.1
|
||||
|
||||
is-network-error@1.1.0: {}
|
||||
|
||||
is-number@7.0.0: {}
|
||||
|
||||
is-plain-obj@2.1.0: {}
|
||||
|
@ -1869,13 +1821,12 @@ snapshots:
|
|||
dependencies:
|
||||
p-limit: 4.0.0
|
||||
|
||||
p-retry@5.1.2:
|
||||
p-retry@6.2.0:
|
||||
dependencies:
|
||||
'@types/retry': 0.12.1
|
||||
'@types/retry': 0.12.2
|
||||
is-network-error: 1.1.0
|
||||
retry: 0.13.1
|
||||
|
||||
packet-reader@1.0.0: {}
|
||||
|
||||
parent-module@1.0.1:
|
||||
dependencies:
|
||||
callsites: 3.1.0
|
||||
|
@ -1908,10 +1859,6 @@ snapshots:
|
|||
dependencies:
|
||||
pg: 8.12.0
|
||||
|
||||
pg-pool@3.6.2(pg@8.8.0):
|
||||
dependencies:
|
||||
pg: 8.8.0
|
||||
|
||||
pg-protocol@1.6.1: {}
|
||||
|
||||
pg-types@2.2.0:
|
||||
|
@ -1942,21 +1889,11 @@ snapshots:
|
|||
optionalDependencies:
|
||||
pg-cloudflare: 1.1.1
|
||||
|
||||
pg@8.8.0:
|
||||
dependencies:
|
||||
buffer-writer: 2.0.0
|
||||
packet-reader: 1.0.0
|
||||
pg-connection-string: 2.6.4
|
||||
pg-pool: 3.6.2(pg@8.8.0)
|
||||
pg-protocol: 1.6.1
|
||||
pg-types: 2.2.0
|
||||
pgpass: 1.0.5
|
||||
|
||||
pgpass@1.0.5:
|
||||
dependencies:
|
||||
split2: 4.2.0
|
||||
|
||||
picocolors@1.0.1: {}
|
||||
picocolors@1.1.0: {}
|
||||
|
||||
picomatch@2.3.1: {}
|
||||
|
||||
|
@ -2068,14 +2005,14 @@ snapshots:
|
|||
|
||||
touch@3.1.1: {}
|
||||
|
||||
ts-node@10.9.2(@types/node@22.5.0)(typescript@5.5.4):
|
||||
ts-node@10.9.2(@types/node@22.5.2)(typescript@5.5.4):
|
||||
dependencies:
|
||||
'@cspotcode/source-map-support': 0.8.1
|
||||
'@tsconfig/node10': 1.0.11
|
||||
'@tsconfig/node12': 1.0.11
|
||||
'@tsconfig/node14': 1.0.3
|
||||
'@tsconfig/node16': 1.0.4
|
||||
'@types/node': 22.5.0
|
||||
'@types/node': 22.5.2
|
||||
acorn: 8.12.1
|
||||
acorn-walk: 8.3.3
|
||||
arg: 4.1.3
|
||||
|
@ -2088,10 +2025,10 @@ snapshots:
|
|||
|
||||
tslib@2.7.0: {}
|
||||
|
||||
tsx@4.17.0:
|
||||
tsx@4.19.0:
|
||||
dependencies:
|
||||
esbuild: 0.23.1
|
||||
get-tsconfig: 4.7.6
|
||||
get-tsconfig: 4.8.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
|
||||
|
@ -2137,7 +2074,7 @@ snapshots:
|
|||
yargs@16.2.0:
|
||||
dependencies:
|
||||
cliui: 7.0.4
|
||||
escalade: 3.1.2
|
||||
escalade: 3.2.0
|
||||
get-caller-file: 2.0.5
|
||||
require-directory: 2.1.1
|
||||
string-width: 4.2.3
|
||||
|
@ -2147,7 +2084,7 @@ snapshots:
|
|||
yargs@17.7.2:
|
||||
dependencies:
|
||||
cliui: 8.0.1
|
||||
escalade: 3.1.2
|
||||
escalade: 3.2.0
|
||||
get-caller-file: 2.0.5
|
||||
require-directory: 2.1.1
|
||||
string-width: 4.2.3
|
||||
|
|
|
@ -4,6 +4,7 @@ import type { Status } from '@futureporn/types'
|
|||
import { createCommand } from '../commands.ts'
|
||||
import { bot } from '../bot.ts'
|
||||
import { configs } from '../config.ts'
|
||||
import { rbacAllow } from '../middlewares/rbac.ts'
|
||||
|
||||
createCommand({
|
||||
name: 'cancel',
|
||||
|
@ -32,6 +33,7 @@ createCommand({
|
|||
|
||||
let vodId: string;
|
||||
try {
|
||||
await rbacAllow(['admin', 'moderator', 'testAdmin'], interaction)
|
||||
const response = await fetch(url, options);
|
||||
|
||||
bot.logger.info(`response.ok=${response.ok}`)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { ApplicationCommandTypes, logger, type Interaction } from '@discordeno/bot'
|
||||
import { createCommand } from '../commands.ts'
|
||||
import getStreamFromDatabase from '../fetchers/getStreamFromDatabase.ts'
|
||||
import patchStreamInDatabase from '../fetchers/patchStreamInDatabase.ts'
|
||||
import patchVod from '../fetchers/patchVod.ts'
|
||||
import { quickAddJob, type WorkerUtilsOptions } from 'graphile-worker'
|
||||
import { configs } from '../config.ts'
|
||||
import findVod from '../fetchers/findVod.ts'
|
||||
|
@ -25,7 +25,7 @@ createCommand({
|
|||
const options: WorkerUtilsOptions = { connectionString: configs.connectionString }
|
||||
logger.info(`now we will quickAddJob process_video`)
|
||||
await quickAddJob(options, 'process_video', { vod_id: vod.id })
|
||||
logger.info(`now we will patchStreamInDatabase`)
|
||||
await patchStreamInDatabase(vod.id, { status: 'processing' })
|
||||
logger.info(`now we will patchVodInDatabase`)
|
||||
await patchVod(vod.id, { status: 'processing' })
|
||||
},
|
||||
})
|
||||
|
|
|
@ -2,8 +2,8 @@ import type { Stream } from "@futureporn/types";
|
|||
import { configs } from "../config.ts";
|
||||
import { logger } from "@discordeno/bot";
|
||||
|
||||
export default async function patchStreamInDatabase(stream_id: string, payload: Partial<Stream>): Promise<void> {
|
||||
const url = `${configs.postgrestUrl}/streams?id=eq.${stream_id}`
|
||||
export default async function patchVod(stream_id: string, payload: Partial<Stream>): Promise<void> {
|
||||
const url = `${configs.postgrestUrl}/vods?id=eq.${stream_id}`
|
||||
const fetchOptions = {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
|
@ -18,7 +18,7 @@ export default async function patchStreamInDatabase(stream_id: string, payload:
|
|||
if (!res.ok) {
|
||||
const body = await res.json()
|
||||
logger.error(body)
|
||||
throw new Error(`Problem during patchStreamInDatabase. res.status=${res.status}, res.statusText=${res.statusText}`)
|
||||
throw new Error(`Problem during patchVod. res.status=${res.status}, res.statusText=${res.statusText}`)
|
||||
}
|
||||
return
|
||||
} catch (e) {
|
|
@ -128,7 +128,7 @@ function getEmbeds(vod: VodResponse, helpers: Helpers) {
|
|||
if (segments) {
|
||||
const getDuration = (s: SegmentResponse) => formatDuration(intervalToDuration({ start: s.created_at, end: s.updated_at }))
|
||||
embeds.newEmbed()
|
||||
.setTitle(`Recording Segments`)
|
||||
.setTitle(`Segments`)
|
||||
.setFields(segments.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime()).map((s, i) => (
|
||||
{
|
||||
name: `Segment ${i+1}`,
|
||||
|
|
|
@ -18,22 +18,22 @@
|
|||
"superclean": "rm -rf node_modules && rm -rf pnpm-lock.yaml && rm -rf dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.617.0",
|
||||
"@aws-sdk/lib-storage": "^3.588.0",
|
||||
"@aws-sdk/client-s3": "^3.637.0",
|
||||
"@aws-sdk/lib-storage": "^3.637.0",
|
||||
"@aws-sdk/types": "^3.609.0",
|
||||
"@futureporn/types": "workspace:^",
|
||||
"@futureporn/utils": "workspace:^",
|
||||
"@paralleldrive/cuid2": "^2.2.2",
|
||||
"@types/chai": "^4.3.16",
|
||||
"@types/chai-as-promised": "^7.1.8",
|
||||
"@types/fluent-ffmpeg": "^2.1.24",
|
||||
"@types/chai": "^4.3.19",
|
||||
"@types/chai-as-promised": "^8.0.0",
|
||||
"@types/fluent-ffmpeg": "^2.1.26",
|
||||
"@types/mocha": "^10.0.7",
|
||||
"@types/qs": "^6.9.15",
|
||||
"date-fns": "^3.6.0",
|
||||
"discord.js": "^14.15.3",
|
||||
"discord.js": "^14.16.1",
|
||||
"diskusage": "^1.2.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"execa": "^6.1.0",
|
||||
"execa": "^9.3.1",
|
||||
"exponential-backoff": "^3.1.1",
|
||||
"fastify": "^4.28.1",
|
||||
"fastify-plugin": "^4.5.1",
|
||||
|
@ -45,41 +45,41 @@
|
|||
"graphile-worker": "^0.16.6",
|
||||
"https": "^1.0.0",
|
||||
"ioredis": "^5.4.1",
|
||||
"minimatch": "^5.1.6",
|
||||
"p-retry": "^5.1.2",
|
||||
"pg-boss": "^9.0.3",
|
||||
"pino-pretty": "^11.2.1",
|
||||
"minimatch": "^10.0.1",
|
||||
"p-retry": "^6.2.0",
|
||||
"pg-boss": "^10.1.1",
|
||||
"pino-pretty": "^11.2.2",
|
||||
"postgres": "^3.4.4",
|
||||
"qs": "^6.13.0",
|
||||
"rxjs": "^7.8.1",
|
||||
"sql": "^0.78.0",
|
||||
"winston": "^3.13.1",
|
||||
"winston": "^3.14.2",
|
||||
"youtube-dl-wrap": "github:insanity54/youtube-dl-wrap"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@smithy/util-stream": "^3.1.2",
|
||||
"@types/node": "^20.14.13",
|
||||
"@smithy/util-stream": "^3.1.3",
|
||||
"@types/node": "^22.5.2",
|
||||
"@types/sinon": "^17.0.3",
|
||||
"@types/sinon-chai": "^3.2.12",
|
||||
"aws-sdk": "^2.1663.0",
|
||||
"aws-sdk": "^2.1687.0",
|
||||
"aws-sdk-client-mock": "^4.0.1",
|
||||
"aws-sdk-mock": "^6.0.4",
|
||||
"chai": "^4.4.1",
|
||||
"aws-sdk-mock": "^6.1.1",
|
||||
"chai": "^5.1.1",
|
||||
"chai-as-promised": "^8.0.0",
|
||||
"cheerio": "1.0.0-rc.12",
|
||||
"mocha": "^10.7.0",
|
||||
"multiformats": "^11.0.2",
|
||||
"cheerio": "1.0.0",
|
||||
"mocha": "^10.7.3",
|
||||
"multiformats": "^13.2.2",
|
||||
"node-abort-controller": "^3.1.1",
|
||||
"node-fetch": "^3.3.2",
|
||||
"nodemon": "^2.0.22",
|
||||
"nodemon": "^3.1.4",
|
||||
"pretty-bytes": "^6.1.1",
|
||||
"s3": "link:aws-sdk/clients/s3",
|
||||
"sinon": "^15.2.0",
|
||||
"sinon-chai": "^3.7.0",
|
||||
"sinon": "^18.0.0",
|
||||
"sinon-chai": "^4.0.0",
|
||||
"sinon-test": "^3.1.6",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsup": "^8.1.2",
|
||||
"tsx": "^4.16.2",
|
||||
"typescript": "^5.5.3"
|
||||
"tsup": "^8.2.4",
|
||||
"tsx": "^4.19.0",
|
||||
"typescript": "^5.5.4"
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
import fastify, { type FastifyRequest } from 'fastify'
|
||||
import { getPackageVersion } from '@futureporn/utils'
|
||||
import { getPackageVersion } from '@futureporn/utils/file.ts'
|
||||
import fastifyGraphileWorkerPlugin, { type ExtendedFastifyInstance } from './fastify-graphile-worker-plugin.ts'
|
||||
import { join, dirname } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
|
|
@ -7,7 +7,7 @@ import 'dotenv/config'
|
|||
import { makeWorkerUtils, type WorkerUtils, Runner, RunnerOptions, run as graphileRun } from 'graphile-worker'
|
||||
import { join, dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { getPackageVersion } from '@futureporn/utils';
|
||||
import { getPackageVersion } from '@futureporn/utils/file.ts';
|
||||
import type { GraphileConfig } from "graphile-config";
|
||||
import type {} from "graphile-worker";
|
||||
|
||||
|
|
|
@ -20,10 +20,12 @@
|
|||
"author": "@cj_clippy",
|
||||
"license": "Unlicense",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.627.0",
|
||||
"@aws-sdk/lib-storage": "^3.588.0",
|
||||
"@aws-sdk/client-s3": "^3.637.0",
|
||||
"@aws-sdk/lib-storage": "^3.637.0",
|
||||
"@futureporn/storage": "workspace:^",
|
||||
"@futureporn/utils": "workspace:^",
|
||||
"@paralleldrive/cuid2": "^2.2.2",
|
||||
"@types/node": "^22.1.0",
|
||||
"@types/node": "^22.5.2",
|
||||
"dotenv": "^16.4.5",
|
||||
"fluture": "^14.0.0",
|
||||
"graphile-worker": "^0.16.6",
|
||||
|
@ -31,9 +33,9 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@futureporn/types": "workspace:^",
|
||||
"@types/ramda": "^0.30.1",
|
||||
"@types/ramda": "^0.30.2",
|
||||
"nodemon": "^3.1.4",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsx": "^4.17.0"
|
||||
"tsx": "^4.19.0"
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -12,7 +12,8 @@ if (!process.env.S3_ACCESS_KEY_ID) throw new Error('Missing S3_ACCESS_KEY_ID env
|
|||
if (!process.env.S3_SECRET_ACCESS_KEY) throw new Error('Missing S3_BUCKET_APPLICATION_KEY env var');
|
||||
if (!process.env.S3_REGION) throw new Error('Missing S3_REGION env var');
|
||||
if (!process.env.S3_ENDPOINT) throw new Error('Missing S3_REGION env var');
|
||||
if (!process.env.S3_BUCKET) throw new Error('Missing S3_BUCKET env var');
|
||||
if (!process.env.S3_MAIN_BUCKET) throw new Error('Missing S3_BUCKET env var');
|
||||
if (!process.env.S3_USC_BUCKET) throw new Error('Missing S3_USC_BUCKET env var');
|
||||
const postgrestUrl = process.env.POSTGREST_URL!
|
||||
const automationUserJwt = process.env.AUTOMATION_USER_JWT!
|
||||
const connectionString = process.env.WORKER_CONNECTION_STRING!
|
||||
|
@ -20,7 +21,8 @@ const s3AccessKeyId = process.env.S3_ACCESS_KEY_ID!
|
|||
const s3Region = process.env.S3_REGION!
|
||||
const s3Endpoint = process.env.S3_ENDPOINT!
|
||||
const s3SecretAccessKey = process.env.S3_SECRET_ACCESS_KEY!
|
||||
const s3Bucket = process.env.S3_BUCKET!
|
||||
const s3MainBucket = process.env.S3_MAIN_BUCKET!
|
||||
const s3UscBucket = process.env.S3_USC_BUCKET!
|
||||
|
||||
export interface Config {
|
||||
postgrestUrl: string;
|
||||
|
@ -30,7 +32,8 @@ export interface Config {
|
|||
s3SecretAccessKey: string;
|
||||
s3Region: string;
|
||||
s3Endpoint: string;
|
||||
s3Bucket: string;
|
||||
s3UscBucket: string;
|
||||
s3MainBucket: string;
|
||||
}
|
||||
|
||||
|
||||
|
@ -42,5 +45,6 @@ export const configs: Config = {
|
|||
s3SecretAccessKey,
|
||||
s3Endpoint,
|
||||
s3Region,
|
||||
s3Bucket,
|
||||
s3MainBucket,
|
||||
s3UscBucket,
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import { configs } from "../config"
|
||||
import type { S3FileRecord, S3FileResponse } from '@futureporn/types'
|
||||
|
||||
export default async function createS3File(s3File?: S3FileRecord): Promise<S3FileResponse|null> {
|
||||
if (!s3File) throw new Error(`first argument passed to createS3File must be a {S3Record}`);
|
||||
console.log(s3File)
|
||||
const url = `${configs.postgrestUrl}/s3_files`
|
||||
const payload: any = {
|
||||
s3_id: s3File.s3_id,
|
||||
s3_key: s3File.s3_key,
|
||||
}
|
||||
const fetchOptions = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${configs.automationUserJwt}`,
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'Prefer': 'return=representation'
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
}
|
||||
const res = await fetch (url, fetchOptions)
|
||||
if (!res.ok) {
|
||||
const body = await res.json()
|
||||
throw new Error(`Problem during createS3File. res.status=${res.status}, res.statusText=${res.statusText}, body=${JSON.stringify(body)}`)
|
||||
}
|
||||
const json = await res.json() as S3FileResponse[]
|
||||
const s3FileRes = json[0]
|
||||
if (!s3FileRes) return null
|
||||
else return s3FileRes
|
||||
}
|
|
@ -1,19 +1,20 @@
|
|||
import { configs } from "../config"
|
||||
import { Helpers } from "graphile-worker"
|
||||
import { Stream } from "@futureporn/types"
|
||||
import type { VodResponse } from "@futureporn/types"
|
||||
|
||||
export default async function getVod(vodId: string, helpers: Helpers) {
|
||||
const url = `${configs.postgrestUrl}/streams?select=*,segments(*)&id=eq.${vodId}`
|
||||
const url = `${configs.postgrestUrl}/vods?select=*,segments(*)&id=eq.${vodId}`
|
||||
try {
|
||||
const res = await fetch(url)
|
||||
if (!res.ok) {
|
||||
throw new Error(`failed fetching stream ${vodId}. status=${res.status}, statusText=${res.statusText}`)
|
||||
throw new Error(`failed fetching getVod ${vodId}. status=${res.status}, statusText=${res.statusText}`)
|
||||
}
|
||||
const body = await res.json() as Stream[]
|
||||
if (!body[0]) throw new Error('body[0] was expected to be Stream data, but it was either null or undefined.');
|
||||
const body = await res.json() as VodResponse[]
|
||||
if (!body[0]) throw new Error('body[0] was expected to be Vod data, but it was either null or undefined.');
|
||||
return body[0];
|
||||
} catch (e) {
|
||||
helpers.logger.error(`encountered an error during getStreamFromDatabase()`)
|
||||
helpers.logger.error(`encountered an error during getVod()`)
|
||||
if (e instanceof Error) {
|
||||
helpers.logger.error(e.message)
|
||||
} else {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import type { Vod } from "@futureporn/types";
|
||||
import type { VodRecord } from "@futureporn/types";
|
||||
import { configs } from "../config.ts";
|
||||
|
||||
|
||||
export default async function patchVodInDatabase(vod_id: string, payload: Partial<Vod>): Promise<void> {
|
||||
export default async function patchVodInDatabase(vod_id: string, payload: Partial<VodRecord>): Promise<void> {
|
||||
const url = `${configs.postgrestUrl}/vods?id=eq.${vod_id}`
|
||||
const fetchOptions = {
|
||||
method: 'PATCH',
|
||||
|
|
|
@ -18,8 +18,8 @@ async function setupGraphileWorker() {
|
|||
taskDirectory: join(__dirname, 'tasks')
|
||||
},
|
||||
};
|
||||
console.log('worker preset as follows')
|
||||
console.log(preset)
|
||||
// console.log('worker preset as follows')
|
||||
// console.log(preset)
|
||||
const runnerOptions: RunnerOptions = {
|
||||
preset
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
import { Helpers, type Task } from 'graphile-worker'
|
||||
import { basename, join } from 'node:path';
|
||||
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3"
|
||||
import { S3Client } from "@aws-sdk/client-s3"
|
||||
import { Upload } from "@aws-sdk/lib-storage"
|
||||
import { createId } from '@paralleldrive/cuid2';
|
||||
// import { downloadS3File, uploadToS3, createStrapiB2File, createStrapiVod, createStrapiStream } from '@futureporn/storage'
|
||||
|
@ -14,14 +14,16 @@ import { writeFile, readFile } from 'node:fs/promises';
|
|||
import { tmpdir } from 'node:os';
|
||||
import { promisify } from 'node:util';
|
||||
import patchVodInDatabase from '../fetchers/patchVodInDatabase'
|
||||
import type { S3File, Stream } from '@futureporn/types';
|
||||
import { downloadFile } from '@futureporn/storage/s3.ts';
|
||||
import { S3FileRecord } from '@futureporn/types';
|
||||
|
||||
interface s3File {
|
||||
interface s3ManifestEntry {
|
||||
key: string;
|
||||
bytes: number;
|
||||
}
|
||||
|
||||
interface Payload {
|
||||
s3_manifest: s3File[];
|
||||
s3_manifest: s3ManifestEntry[];
|
||||
vod_id?: string;
|
||||
}
|
||||
|
||||
|
@ -46,21 +48,6 @@ function assertPayload(payload: any): asserts payload is Payload {
|
|||
}
|
||||
|
||||
|
||||
const downloadS3File = async function (client: S3Client, s3File: s3File): Promise<string> {
|
||||
const bucket = configs.s3Bucket;
|
||||
const { key } = s3File
|
||||
console.log(`downloadS3File with s3File key=${key}, bucket=${bucket}`)
|
||||
const getObjectCommand = new GetObjectCommand({ Bucket: bucket, Key: key })
|
||||
const response = await client.send(getObjectCommand)
|
||||
if (!response) throw new Error(`failed to receive a response while calling S3 GetObjectCommand (within downloadS3File)`);
|
||||
if (!response.Body) throw new Error('S3 GetObjectCommand response did not have a Body (within downloadS3File)');
|
||||
const readStream = response.Body as Readable
|
||||
const outputFilePath = join(tmpdir(), key)
|
||||
const writeStream = createWriteStream(outputFilePath)
|
||||
const pipelinePromise = promisify(pipeline)
|
||||
await pipelinePromise(readStream, writeStream)
|
||||
return outputFilePath
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -177,7 +164,7 @@ export const combine_video_segments: Task = async function (payload: unknown, he
|
|||
// helpers.logger.info(JSON.stringify(payload?.s3_manifest))
|
||||
assertPayload(payload)
|
||||
const { s3_manifest, vod_id } = payload
|
||||
if (!vod_id) helpers.logger.warn(`combine_video_segments was called without a vod_id. This is not recommended.`);
|
||||
if (!vod_id) throw new Error('combine_video_segments was called without a vod_id.');
|
||||
helpers.logger.info(`combine_video_segments started with s3_manifest=${JSON.stringify(s3_manifest)}, vod_id=${vod_id}`)
|
||||
|
||||
/**
|
||||
|
@ -205,7 +192,7 @@ export const combine_video_segments: Task = async function (payload: unknown, he
|
|||
}
|
||||
});
|
||||
const s3Manifest = s3_manifest
|
||||
const inputVideoFilePaths = await Promise.all(s3Manifest.map((m) => downloadS3File(client, m)))
|
||||
const inputVideoFilePaths = await Promise.all(s3Manifest.filter((m) => (m.bytes !== 0)).map((m) => downloadFile(client, configs.s3UscBucket, m.key)))
|
||||
const concatenatedVideoFile = await concatVideos(inputVideoFilePaths)
|
||||
const s3KeyName = basename(concatenatedVideoFile)
|
||||
const inputStream = createReadStream(concatenatedVideoFile)
|
||||
|
@ -214,19 +201,18 @@ export const combine_video_segments: Task = async function (payload: unknown, he
|
|||
setupUploadPipeline({ inputStream, uploadStream })
|
||||
await upload.done()
|
||||
|
||||
|
||||
if (vod_id) {
|
||||
if (!vod_id) throw new Error('vod_id was missing from payload');
|
||||
// update the vod with the s3_file of the combined video
|
||||
const s3File: S3File = {
|
||||
const s3File: S3FileRecord = {
|
||||
s3_key: s3KeyName,
|
||||
bucket: configs.s3Bucket,
|
||||
bucket: configs.s3UscBucket,
|
||||
}
|
||||
const payload = {
|
||||
s3_file: s3File,
|
||||
stream_id
|
||||
vod_id
|
||||
}
|
||||
await patchVodInDatabase(vod_id, payload)
|
||||
}
|
||||
|
||||
|
||||
} catch (e: any) {
|
||||
helpers.logger.error('combined_video_segments failed')
|
||||
|
@ -235,6 +221,7 @@ export const combine_video_segments: Task = async function (payload: unknown, he
|
|||
} else {
|
||||
helpers.logger.error(e)
|
||||
}
|
||||
throw e
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
import type { Task, Helpers } from "graphile-worker";
|
||||
import getVod from "../fetchers/getVod";
|
||||
import { getStoryboard } from '@futureporn/utils/image.ts'
|
||||
import { getCdnUrl, uploadFile, s3CdnMap, type S3FileArgs } from '@futureporn/storage/s3.ts'
|
||||
import patchVodInDatabase from "../fetchers/patchVodInDatabase";
|
||||
import { configs } from "../config";
|
||||
import { basename } from "path";
|
||||
|
||||
interface Payload {
|
||||
vod_id: string;
|
||||
}
|
||||
|
||||
function assertPayload(payload: any): asserts payload is Payload {
|
||||
if (typeof payload !== "object" || !payload) throw new Error("invalid payload (it must be an object)");
|
||||
if (typeof payload.vod_id !== "string") throw new Error("payload.vod_id was not a string");
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const generate_thumbnail: Task = async function (payload: unknown, helpers: Helpers) {
|
||||
assertPayload(payload)
|
||||
const { vod_id } = payload
|
||||
if (!vod_id) throw new Error('generate_thumbnail Task was started without a vod_id. This is unsupported.');
|
||||
helpers.logger.info(`generate_thumbnail started with vod_id=${vod_id}`);
|
||||
|
||||
const vod = await getVod(vod_id, helpers)
|
||||
const s3_file = vod?.s3_file
|
||||
if (!s3_file) throw new Error(`vod ${vod_id} was missing a s3_file.`);
|
||||
|
||||
// we need to get a CDN url to the vod so we can download chunks of the file in order for Prevvy to create the storyboard image.
|
||||
const cdnUrl = getCdnUrl(configs.s3Bucket, s3_file.s3_key)
|
||||
|
||||
const tmpImagePath = await getStoryboard(cdnUrl)
|
||||
|
||||
|
||||
// we need to upload the image to S3
|
||||
const uploadArgs: S3FileArgs = {
|
||||
filePath: tmpImagePath,
|
||||
s3AccessKeyId: configs.s3AccessKeyId,
|
||||
s3SecretAccessKey: configs.s3SecretAccessKey,
|
||||
s3BucketName: configs.s3Bucket,
|
||||
s3Endpoint: configs.s3Region,
|
||||
s3Region: configs.s3Region
|
||||
}
|
||||
const upload = await uploadFile(uploadArgs)
|
||||
if (!upload) throw new Error(`failed to upload ${tmpImagePath} to S3`);
|
||||
if (!upload.Key) throw new Error(`failed to upload ${tmpImagePath} to S3 (upload.Key was missing)`);
|
||||
|
||||
// we need to create a S3 file in the db
|
||||
const thumbnail = getCdnUrl(configs.s3Bucket, upload.Key)
|
||||
await patchVodInDatabase(vod_id, { thumbnail })
|
||||
|
||||
|
||||
}
|
||||
|
||||
export default generate_thumbnail
|
|
@ -28,6 +28,7 @@ function assertPayload(payload: any): asserts payload is Payload {
|
|||
* For example, combine_video_segments is only useful on a vod recording which ended up with multiple segments.
|
||||
*
|
||||
* - combine_video_segments
|
||||
* - remux_video
|
||||
* - generate_thumbnail
|
||||
* - queue_moderator_review
|
||||
* - create_mux_asset
|
||||
|
@ -35,15 +36,8 @@ function assertPayload(payload: any): asserts payload is Payload {
|
|||
*
|
||||
* Some of the above Tasks are dependent on others. generate_thumbnail and everything following it depends on combine_video_segments.
|
||||
* graphile-worker doesn't have support for dependent tasks,
|
||||
* thus our solution is to run process_video as many times as needed, each time adding as many parallel tasks as possible.
|
||||
*
|
||||
* For the first run, we add only combine_video_segments, which itself will add process_video when it's done.
|
||||
* The second run can tell that combine_video_segments has successfully completed it's task, so it doesn't run it a second time.
|
||||
* generate_thumbnail runs next, after which it itself adds process_video to the work queue.
|
||||
*
|
||||
* On the third run, combine_video_segments and generate_thumbnail are skipped due to idempotency.
|
||||
* The three next tasks are added simultaneously for parallel execution-- queue_moderator_review, create_mux_asset, and create_torrent.
|
||||
*
|
||||
* thus our solution is to invoke ALL the above jobs immediately, and build those jobs to fail if pre-conditions are unmet.
|
||||
* all listed jobs are also idempotent, which means if they don't need to run (previously already performed their tasks), they will exit without doing anything.
|
||||
*
|
||||
*/
|
||||
const process_video: Task = async function (payload: unknown, helpers: Helpers) {
|
||||
|
@ -51,16 +45,30 @@ const process_video: Task = async function (payload: unknown, helpers: Helpers)
|
|||
const { vod_id } = payload
|
||||
helpers.logger.info(`process_video task has begun for vod_id=${vod_id}`)
|
||||
|
||||
|
||||
const vod = await getVod(vod_id, helpers)
|
||||
if (!vod) throw new Error(`failed to get vod from database.`);
|
||||
if (!vod.segments) throw new Error(`vod ${vod_id} fetched from database lacked any segments.`);
|
||||
|
||||
const isCombinationNeeded = (vod.segments.length > 1)
|
||||
if (isCombinationNeeded) {
|
||||
const s3_manifest = vod.segments.map((segment) => ({ key: segment.s3_key }))
|
||||
const s3_manifest = vod.segments.map((segment) => ({ key: segment.s3_key, bytes: segment.bytes }))
|
||||
helpers.logger.info(`There are ${vod.segments.length} segments; Concatenation is needed.`)
|
||||
helpers.addJob('combine_video_segments', { s3_manifest, vod_id })
|
||||
} else {
|
||||
helpers.addJob('remux_video', { vod_id })
|
||||
}
|
||||
|
||||
helpers.addJob('generate_thumbnail', { vod_id })
|
||||
// helpers.addJob('queue_moderator_review', { })
|
||||
// helpers.addJob('create_mux_asset', { })
|
||||
// helpers.addJob('create_torrent', { })
|
||||
// helpers.addJob('create_ipfs', { })
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
export default process_video;
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
import type { Helpers, Task } from "graphile-worker"
|
||||
import { configs } from "../config"
|
||||
import getVod from "../fetchers/getVod"
|
||||
import { downloadFile, uploadFile, type S3FileArgs } from "@futureporn/storage/s3.ts"
|
||||
import { remux } from '@futureporn/utils/video.ts'
|
||||
import { getTmpFile } from "@futureporn/utils/file.ts"
|
||||
import { basename } from "node:path"
|
||||
import patchVodInDatabase from "../fetchers/patchVodInDatabase"
|
||||
|
||||
interface Payload {
|
||||
vod_id: string;
|
||||
}
|
||||
|
||||
function assertPayload(payload: any): asserts payload is Payload {
|
||||
if (typeof payload !== "object" || !payload) throw new Error("invalid payload (it must be an object)");
|
||||
if (typeof payload.vod_id !== "string") throw new Error("payload.vod_id was not a string");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* # remux_video
|
||||
*
|
||||
* convert a .ts video file to a .mp4 video file (safely, without loss of quality)
|
||||
*/
|
||||
const remux_video: Task = async function (payload: unknown, helpers: Helpers) {
|
||||
assertPayload(payload)
|
||||
const { vod_id } = payload
|
||||
helpers.logger.info(`remux_video task has begun for vod_id=${vod_id}`)
|
||||
|
||||
|
||||
const vod = await getVod(vod_id, helpers)
|
||||
if (!vod) throw new Error(`failed to get vod from database.`);
|
||||
if (!vod.segments) throw new Error(`vod ${vod_id} fetched from database lacked any segments.`);
|
||||
if (!vod.segments.at(0)) throw new Error(`vod ${vod_id} lacked a recorded segment.`);
|
||||
if (!vod.segments.at(0)?.s3_key) throw new Error(`vod ${vod_id} lacked a recorded segment s3_key name.`);
|
||||
|
||||
const segmentFileName = vod.segments.at(0)!.s3_key
|
||||
if (!segmentFileName.endsWith('.ts')) throw new Error(`vod ${vod_id} recording segment ${segmentFileName} did not end with .ts, which is expected.`);
|
||||
|
||||
const moreThanOneSegment = (vod.segments.length > 1)
|
||||
if (moreThanOneSegment) {
|
||||
throw new Error(`remux_video was given vod=${vod_id} which has more than one segment. This is unsupported. (use combine_video_segments Task to combine multiple videos)`);
|
||||
}
|
||||
|
||||
const tmpFilePath = getTmpFile(segmentFileName)
|
||||
const downloadArgs: S3FileArgs = {
|
||||
filePath: tmpFilePath,
|
||||
s3AccessKeyId: configs.s3AccessKeyId,
|
||||
s3SecretAccessKey: configs.s3SecretAccessKey,
|
||||
s3BucketName: configs.s3Bucket,
|
||||
s3Endpoint: configs.s3Region,
|
||||
s3Region: configs.s3Region
|
||||
}
|
||||
await downloadFile(downloadArgs)
|
||||
|
||||
helpers.logger.info('Remuxing the video')
|
||||
const outputVideoPath = getTmpFile(`${basename(segmentFileName, '.ts')}.mp4`)
|
||||
await remux(tmpFilePath, outputVideoPath)
|
||||
|
||||
helpers.logger.info('Uploading the remuxed video')
|
||||
const uploadArgs: S3FileArgs = {
|
||||
filePath: outputVideoPath,
|
||||
s3AccessKeyId: configs.s3AccessKeyId,
|
||||
s3SecretAccessKey: configs.s3SecretAccessKey,
|
||||
s3BucketName: configs.s3Bucket,
|
||||
s3Endpoint: configs.s3Region,
|
||||
s3Region: configs.s3Region
|
||||
}
|
||||
const upload = await uploadFile(uploadArgs)
|
||||
|
||||
helpers.logger.info('Patching the vod in the database')
|
||||
await patchVodInDatabase(vod_id, { s3_file: upload?.Key })
|
||||
|
||||
}
|
||||
|
||||
export default remux_video;
|
|
@ -15,30 +15,29 @@
|
|||
"license": "Unlicense",
|
||||
"devDependencies": {
|
||||
"@esbuild-plugins/esm-externals": "^0.1.2",
|
||||
"@futureporn/image": "workspace:^",
|
||||
"@futureporn/scout": "workspace:^",
|
||||
"@futureporn/storage": "workspace:^",
|
||||
"@futureporn/types": "workspace:^",
|
||||
"@futureporn/utils": "workspace:^",
|
||||
"@types/chai": "^4.3.16",
|
||||
"@types/imapflow": "^1.0.18",
|
||||
"@types/chai": "^4.3.19",
|
||||
"@types/imapflow": "^1.0.19",
|
||||
"@types/mailparser": "^3.4.4",
|
||||
"@types/mocha": "^10.0.7",
|
||||
"chai": "^5.1.1",
|
||||
"mocha": "^10.7.0",
|
||||
"tsup": "^8.1.2",
|
||||
"typescript": "^5.5.3"
|
||||
"mocha": "^10.7.3",
|
||||
"tsup": "^8.2.4",
|
||||
"typescript": "^5.5.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": "^20.14.9",
|
||||
"@types/node": "^22.5.2",
|
||||
"@types/qs": "^6.9.15",
|
||||
"cheerio": "1.0.0-rc.12",
|
||||
"cheerio": "1.0.0",
|
||||
"date-fns": "^3.6.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"fastify": "^4.12.0",
|
||||
"fastify": "^4.28.1",
|
||||
"graphile-worker": "^0.16.6",
|
||||
"imapflow": "^1.0.164",
|
||||
"mailparser": "^3.7.1",
|
||||
"qs": "^6.12.3"
|
||||
"qs": "^6.13.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,14 +9,14 @@ importers:
|
|||
.:
|
||||
dependencies:
|
||||
'@types/node':
|
||||
specifier: ^20.14.9
|
||||
version: 20.16.1
|
||||
specifier: ^22.5.2
|
||||
version: 22.5.2
|
||||
'@types/qs':
|
||||
specifier: ^6.9.15
|
||||
version: 6.9.15
|
||||
cheerio:
|
||||
specifier: 1.0.0-rc.12
|
||||
version: 1.0.0-rc.12
|
||||
specifier: 1.0.0
|
||||
version: 1.0.0
|
||||
date-fns:
|
||||
specifier: ^3.6.0
|
||||
version: 3.6.0
|
||||
|
@ -24,7 +24,7 @@ importers:
|
|||
specifier: ^16.4.5
|
||||
version: 16.4.5
|
||||
fastify:
|
||||
specifier: ^4.12.0
|
||||
specifier: ^4.28.1
|
||||
version: 4.28.1
|
||||
graphile-worker:
|
||||
specifier: ^0.16.6
|
||||
|
@ -36,18 +36,15 @@ importers:
|
|||
specifier: ^3.7.1
|
||||
version: 3.7.1
|
||||
qs:
|
||||
specifier: ^6.12.3
|
||||
specifier: ^6.13.0
|
||||
version: 6.13.0
|
||||
devDependencies:
|
||||
'@esbuild-plugins/esm-externals':
|
||||
specifier: ^0.1.2
|
||||
version: 0.1.2(esbuild@0.23.1)
|
||||
'@futureporn/image':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/image
|
||||
'@futureporn/scout':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/scout
|
||||
version: link:../scout
|
||||
'@futureporn/storage':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/storage
|
||||
|
@ -58,10 +55,10 @@ importers:
|
|||
specifier: workspace:^
|
||||
version: link:../../packages/utils
|
||||
'@types/chai':
|
||||
specifier: ^4.3.16
|
||||
version: 4.3.17
|
||||
specifier: ^4.3.19
|
||||
version: 4.3.19
|
||||
'@types/imapflow':
|
||||
specifier: ^1.0.18
|
||||
specifier: ^1.0.19
|
||||
version: 1.0.19
|
||||
'@types/mailparser':
|
||||
specifier: ^3.4.4
|
||||
|
@ -73,13 +70,13 @@ importers:
|
|||
specifier: ^5.1.1
|
||||
version: 5.1.1
|
||||
mocha:
|
||||
specifier: ^10.7.0
|
||||
specifier: ^10.7.3
|
||||
version: 10.7.3
|
||||
tsup:
|
||||
specifier: ^8.1.2
|
||||
specifier: ^8.2.4
|
||||
version: 8.2.4(typescript@5.5.4)
|
||||
typescript:
|
||||
specifier: ^5.5.3
|
||||
specifier: ^5.5.4
|
||||
version: 5.5.4
|
||||
|
||||
packages:
|
||||
|
@ -298,91 +295,91 @@ packages:
|
|||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.21.0':
|
||||
resolution: {integrity: sha512-WTWD8PfoSAJ+qL87lE7votj3syLavxunWhzCnx3XFxFiI/BA/r3X7MUM8dVrH8rb2r4AiO8jJsr3ZjdaftmnfA==}
|
||||
'@rollup/rollup-android-arm-eabi@4.21.2':
|
||||
resolution: {integrity: sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@rollup/rollup-android-arm64@4.21.0':
|
||||
resolution: {integrity: sha512-a1sR2zSK1B4eYkiZu17ZUZhmUQcKjk2/j9Me2IDjk1GHW7LB5Z35LEzj9iJch6gtUfsnvZs1ZNyDW2oZSThrkA==}
|
||||
'@rollup/rollup-android-arm64@4.21.2':
|
||||
resolution: {integrity: sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@rollup/rollup-darwin-arm64@4.21.0':
|
||||
resolution: {integrity: sha512-zOnKWLgDld/svhKO5PD9ozmL6roy5OQ5T4ThvdYZLpiOhEGY+dp2NwUmxK0Ld91LrbjrvtNAE0ERBwjqhZTRAA==}
|
||||
'@rollup/rollup-darwin-arm64@4.21.2':
|
||||
resolution: {integrity: sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@rollup/rollup-darwin-x64@4.21.0':
|
||||
resolution: {integrity: sha512-7doS8br0xAkg48SKE2QNtMSFPFUlRdw9+votl27MvT46vo44ATBmdZdGysOevNELmZlfd+NEa0UYOA8f01WSrg==}
|
||||
'@rollup/rollup-darwin-x64@4.21.2':
|
||||
resolution: {integrity: sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.21.0':
|
||||
resolution: {integrity: sha512-pWJsfQjNWNGsoCq53KjMtwdJDmh/6NubwQcz52aEwLEuvx08bzcy6tOUuawAOncPnxz/3siRtd8hiQ32G1y8VA==}
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.21.2':
|
||||
resolution: {integrity: sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.21.0':
|
||||
resolution: {integrity: sha512-efRIANsz3UHZrnZXuEvxS9LoCOWMGD1rweciD6uJQIx2myN3a8Im1FafZBzh7zk1RJ6oKcR16dU3UPldaKd83w==}
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.21.2':
|
||||
resolution: {integrity: sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.21.0':
|
||||
resolution: {integrity: sha512-ZrPhydkTVhyeGTW94WJ8pnl1uroqVHM3j3hjdquwAcWnmivjAwOYjTEAuEDeJvGX7xv3Z9GAvrBkEzCgHq9U1w==}
|
||||
'@rollup/rollup-linux-arm64-gnu@4.21.2':
|
||||
resolution: {integrity: sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.21.0':
|
||||
resolution: {integrity: sha512-cfaupqd+UEFeURmqNP2eEvXqgbSox/LHOyN9/d2pSdV8xTrjdg3NgOFJCtc1vQ/jEke1qD0IejbBfxleBPHnPw==}
|
||||
'@rollup/rollup-linux-arm64-musl@4.21.2':
|
||||
resolution: {integrity: sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-powerpc64le-gnu@4.21.0':
|
||||
resolution: {integrity: sha512-ZKPan1/RvAhrUylwBXC9t7B2hXdpb/ufeu22pG2psV7RN8roOfGurEghw1ySmX/CmDDHNTDDjY3lo9hRlgtaHg==}
|
||||
'@rollup/rollup-linux-powerpc64le-gnu@4.21.2':
|
||||
resolution: {integrity: sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.21.0':
|
||||
resolution: {integrity: sha512-H1eRaCwd5E8eS8leiS+o/NqMdljkcb1d6r2h4fKSsCXQilLKArq6WS7XBLDu80Yz+nMqHVFDquwcVrQmGr28rg==}
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.21.2':
|
||||
resolution: {integrity: sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.21.0':
|
||||
resolution: {integrity: sha512-zJ4hA+3b5tu8u7L58CCSI0A9N1vkfwPhWd/puGXwtZlsB5bTkwDNW/+JCU84+3QYmKpLi+XvHdmrlwUwDA6kqw==}
|
||||
'@rollup/rollup-linux-s390x-gnu@4.21.2':
|
||||
resolution: {integrity: sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.21.0':
|
||||
resolution: {integrity: sha512-e2hrvElFIh6kW/UNBQK/kzqMNY5mO+67YtEh9OA65RM5IJXYTWiXjX6fjIiPaqOkBthYF1EqgiZ6OXKcQsM0hg==}
|
||||
'@rollup/rollup-linux-x64-gnu@4.21.2':
|
||||
resolution: {integrity: sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.21.0':
|
||||
resolution: {integrity: sha512-1vvmgDdUSebVGXWX2lIcgRebqfQSff0hMEkLJyakQ9JQUbLDkEaMsPTLOmyccyC6IJ/l3FZuJbmrBw/u0A0uCQ==}
|
||||
'@rollup/rollup-linux-x64-musl@4.21.2':
|
||||
resolution: {integrity: sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.21.0':
|
||||
resolution: {integrity: sha512-s5oFkZ/hFcrlAyBTONFY1TWndfyre1wOMwU+6KCpm/iatybvrRgmZVM+vCFwxmC5ZhdlgfE0N4XorsDpi7/4XQ==}
|
||||
'@rollup/rollup-win32-arm64-msvc@4.21.2':
|
||||
resolution: {integrity: sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-ia32-msvc@4.21.0':
|
||||
resolution: {integrity: sha512-G9+TEqRnAA6nbpqyUqgTiopmnfgnMkR3kMukFBDsiyy23LZvUCpiUwjTRx6ezYCjJODXrh52rBR9oXvm+Fp5wg==}
|
||||
'@rollup/rollup-win32-ia32-msvc@4.21.2':
|
||||
resolution: {integrity: sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-x64-msvc@4.21.0':
|
||||
resolution: {integrity: sha512-2jsCDZwtQvRhejHLfZ1JY6w6kEuEtfF9nzYsZxzSlNVKDX+DpsDJ+Rbjkm74nvg2rdx0gwBS+IMdvwJuq3S9pQ==}
|
||||
'@rollup/rollup-win32-x64-msvc@4.21.2':
|
||||
resolution: {integrity: sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@selderee/plugin-htmlparser2@0.11.0':
|
||||
resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==}
|
||||
|
||||
'@types/chai@4.3.17':
|
||||
resolution: {integrity: sha512-zmZ21EWzR71B4Sscphjief5djsLre50M6lI622OSySTmn9DB3j+C3kWroHfBQWXbOBwbgg/M8CG/hUxDLIloow==}
|
||||
'@types/chai@4.3.19':
|
||||
resolution: {integrity: sha512-2hHHvQBVE2FiSK4eN0Br6snX9MtolHaTo/batnLjlGRhoQzlCL61iVpxoqO7SfFyOw+P/pwv+0zNHzKoGWz9Cw==}
|
||||
|
||||
'@types/debug@4.1.12':
|
||||
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
||||
|
@ -405,11 +402,14 @@ packages:
|
|||
'@types/ms@0.7.34':
|
||||
resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==}
|
||||
|
||||
'@types/node@20.16.1':
|
||||
resolution: {integrity: sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==}
|
||||
'@types/node@20.16.3':
|
||||
resolution: {integrity: sha512-/wdGiWRkMOm53gAsSyFMXFZHbVg7C6CbkrzHNpaHoYfsUWPg7m6ZRKtvQjgvQ9i8WT540a3ydRlRQbxjY30XxQ==}
|
||||
|
||||
'@types/pg@8.11.6':
|
||||
resolution: {integrity: sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==}
|
||||
'@types/node@22.5.2':
|
||||
resolution: {integrity: sha512-acJsPTEqYqulZS/Yp/S3GgeE6GZ0qYODUR8aVr/DkhHQ8l9nd4j5x1/ZJy9/gHrRlFMqkO6i0I3E27Alu4jjPg==}
|
||||
|
||||
'@types/pg@8.11.8':
|
||||
resolution: {integrity: sha512-IqpCf8/569txXN/HoP5i1LjXfKZWL76Yr2R77xgeIICUbAYHeoaEZFhYHo2uDftecLWrTJUq63JvQu8q3lnDyA==}
|
||||
|
||||
'@types/qs@6.9.15':
|
||||
resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==}
|
||||
|
@ -559,9 +559,9 @@ packages:
|
|||
cheerio-select@2.1.0:
|
||||
resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==}
|
||||
|
||||
cheerio@1.0.0-rc.12:
|
||||
resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==}
|
||||
engines: {node: '>= 6'}
|
||||
cheerio@1.0.0:
|
||||
resolution: {integrity: sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==}
|
||||
engines: {node: '>=18.17'}
|
||||
|
||||
chokidar@3.6.0:
|
||||
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
|
||||
|
@ -693,6 +693,9 @@ packages:
|
|||
resolution: {integrity: sha512-EuJWwlHPZ1LbADuKTClvHtwbaFn4rOD+dRAbWysqEOXRc2Uui0hJInNJrsdH0c+OhJA4nrCBdSkW4DD5YxAo6A==}
|
||||
engines: {node: '>=8.10.0'}
|
||||
|
||||
encoding-sniffer@0.2.0:
|
||||
resolution: {integrity: sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==}
|
||||
|
||||
entities@4.5.0:
|
||||
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
||||
engines: {node: '>=0.12'}
|
||||
|
@ -713,8 +716,8 @@ packages:
|
|||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
escalade@3.1.2:
|
||||
resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
|
||||
escalade@3.2.0:
|
||||
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
escape-string-regexp@1.0.5:
|
||||
|
@ -885,6 +888,9 @@ packages:
|
|||
htmlparser2@8.0.2:
|
||||
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
|
||||
|
||||
htmlparser2@9.1.0:
|
||||
resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==}
|
||||
|
||||
human-signals@2.1.0:
|
||||
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
|
||||
engines: {node: '>=10.17.0'}
|
||||
|
@ -1160,6 +1166,9 @@ packages:
|
|||
parse5-htmlparser2-tree-adapter@7.0.0:
|
||||
resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==}
|
||||
|
||||
parse5-parser-stream@7.1.2:
|
||||
resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==}
|
||||
|
||||
parse5@7.1.2:
|
||||
resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==}
|
||||
|
||||
|
@ -1231,8 +1240,8 @@ packages:
|
|||
pgpass@1.0.5:
|
||||
resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==}
|
||||
|
||||
picocolors@1.0.1:
|
||||
resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
|
||||
picocolors@1.1.0:
|
||||
resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==}
|
||||
|
||||
picomatch@2.3.1:
|
||||
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
|
||||
|
@ -1248,8 +1257,8 @@ packages:
|
|||
resolution: {integrity: sha512-g3/hpwfujK5a4oVbaefoJxezLzsDgLcNJeITvC6yrfwYeT9la+edCK42j5QpEQSQCZgTKapXvnQIdgZwvRaZug==}
|
||||
hasBin: true
|
||||
|
||||
pino@9.3.2:
|
||||
resolution: {integrity: sha512-WtARBjgZ7LNEkrGWxMBN/jvlFiE17LTbBoH0konmBU684Kd0uIiDwBXlcTCW7iJnA6HfIKwUssS/2AC6cDEanw==}
|
||||
pino@9.4.0:
|
||||
resolution: {integrity: sha512-nbkQb5+9YPhQRz/BeQmrWpEknAaqjpAqRK8NwJpmrX/JHu7JuZC5G1CeAwJDJfGes4h+YihC6in3Q2nGb+Y09w==}
|
||||
hasBin: true
|
||||
|
||||
pirates@4.0.6:
|
||||
|
@ -1383,8 +1392,8 @@ packages:
|
|||
rfdc@1.4.1:
|
||||
resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
|
||||
|
||||
rollup@4.21.0:
|
||||
resolution: {integrity: sha512-vo+S/lfA2lMS7rZ2Qoubi6I5hwZwzXeUIctILZLbHI+laNtvhhOIon2S1JksA5UEDQ7l3vberd0fxK44lTYjbQ==}
|
||||
rollup@4.21.2:
|
||||
resolution: {integrity: sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
hasBin: true
|
||||
|
||||
|
@ -1397,8 +1406,8 @@ packages:
|
|||
safe-regex2@3.1.0:
|
||||
resolution: {integrity: sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug==}
|
||||
|
||||
safe-stable-stringify@2.4.3:
|
||||
resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==}
|
||||
safe-stable-stringify@2.5.0:
|
||||
resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
safer-buffer@2.1.2:
|
||||
|
@ -1456,8 +1465,8 @@ packages:
|
|||
resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==}
|
||||
engines: {node: '>= 10.0.0', npm: '>= 3.0.0'}
|
||||
|
||||
sonic-boom@4.0.1:
|
||||
resolution: {integrity: sha512-hTSD/6JMLyT4r9zeof6UtuBDpjJ9sO08/nmS5djaA9eozT9oOlNdpXSnzcgj4FTqpk3nkLrs61l4gip9r1HCrQ==}
|
||||
sonic-boom@4.1.0:
|
||||
resolution: {integrity: sha512-NGipjjRicyJJ03rPiZCJYjwlsuP2d1/5QUviozRXC7S3WdVWNK5e3Ojieb9CCyfhq2UC+3+SRd9nG3I2lPRvUw==}
|
||||
|
||||
source-map@0.8.0-beta.0:
|
||||
resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==}
|
||||
|
@ -1579,9 +1588,21 @@ packages:
|
|||
undici-types@6.19.8:
|
||||
resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
|
||||
|
||||
undici@6.19.8:
|
||||
resolution: {integrity: sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==}
|
||||
engines: {node: '>=18.17'}
|
||||
|
||||
webidl-conversions@4.0.2:
|
||||
resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
|
||||
|
||||
whatwg-encoding@3.1.1:
|
||||
resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
whatwg-mimetype@4.0.0:
|
||||
resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
whatwg-url@7.1.0:
|
||||
resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==}
|
||||
|
||||
|
@ -1641,7 +1662,7 @@ snapshots:
|
|||
'@babel/code-frame@7.24.7':
|
||||
dependencies:
|
||||
'@babel/highlight': 7.24.7
|
||||
picocolors: 1.0.1
|
||||
picocolors: 1.1.0
|
||||
|
||||
'@babel/helper-validator-identifier@7.24.7': {}
|
||||
|
||||
|
@ -1650,7 +1671,7 @@ snapshots:
|
|||
'@babel/helper-validator-identifier': 7.24.7
|
||||
chalk: 2.4.2
|
||||
js-tokens: 4.0.0
|
||||
picocolors: 1.0.1
|
||||
picocolors: 1.1.0
|
||||
|
||||
'@esbuild-plugins/esm-externals@0.1.2(esbuild@0.23.1)':
|
||||
dependencies:
|
||||
|
@ -1791,52 +1812,52 @@ snapshots:
|
|||
'@pkgjs/parseargs@0.11.0':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.21.0':
|
||||
'@rollup/rollup-android-arm-eabi@4.21.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-android-arm64@4.21.0':
|
||||
'@rollup/rollup-android-arm64@4.21.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-darwin-arm64@4.21.0':
|
||||
'@rollup/rollup-darwin-arm64@4.21.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-darwin-x64@4.21.0':
|
||||
'@rollup/rollup-darwin-x64@4.21.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.21.0':
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.21.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.21.0':
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.21.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.21.0':
|
||||
'@rollup/rollup-linux-arm64-gnu@4.21.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.21.0':
|
||||
'@rollup/rollup-linux-arm64-musl@4.21.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-powerpc64le-gnu@4.21.0':
|
||||
'@rollup/rollup-linux-powerpc64le-gnu@4.21.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.21.0':
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.21.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.21.0':
|
||||
'@rollup/rollup-linux-s390x-gnu@4.21.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.21.0':
|
||||
'@rollup/rollup-linux-x64-gnu@4.21.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.21.0':
|
||||
'@rollup/rollup-linux-x64-musl@4.21.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.21.0':
|
||||
'@rollup/rollup-win32-arm64-msvc@4.21.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-ia32-msvc@4.21.0':
|
||||
'@rollup/rollup-win32-ia32-msvc@4.21.2':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-x64-msvc@4.21.0':
|
||||
'@rollup/rollup-win32-x64-msvc@4.21.2':
|
||||
optional: true
|
||||
|
||||
'@selderee/plugin-htmlparser2@0.11.0':
|
||||
|
@ -1844,7 +1865,7 @@ snapshots:
|
|||
domhandler: 5.0.3
|
||||
selderee: 0.11.0
|
||||
|
||||
'@types/chai@4.3.17': {}
|
||||
'@types/chai@4.3.19': {}
|
||||
|
||||
'@types/debug@4.1.12':
|
||||
dependencies:
|
||||
|
@ -1854,28 +1875,32 @@ snapshots:
|
|||
|
||||
'@types/imapflow@1.0.19':
|
||||
dependencies:
|
||||
'@types/node': 20.16.1
|
||||
'@types/node': 22.5.2
|
||||
|
||||
'@types/interpret@1.1.3':
|
||||
dependencies:
|
||||
'@types/node': 20.16.1
|
||||
'@types/node': 22.5.2
|
||||
|
||||
'@types/mailparser@3.4.4':
|
||||
dependencies:
|
||||
'@types/node': 20.16.1
|
||||
'@types/node': 22.5.2
|
||||
iconv-lite: 0.6.3
|
||||
|
||||
'@types/mocha@10.0.7': {}
|
||||
|
||||
'@types/ms@0.7.34': {}
|
||||
|
||||
'@types/node@20.16.1':
|
||||
'@types/node@20.16.3':
|
||||
dependencies:
|
||||
undici-types: 6.19.8
|
||||
|
||||
'@types/pg@8.11.6':
|
||||
'@types/node@22.5.2':
|
||||
dependencies:
|
||||
'@types/node': 20.16.1
|
||||
undici-types: 6.19.8
|
||||
|
||||
'@types/pg@8.11.8':
|
||||
dependencies:
|
||||
'@types/node': 22.5.2
|
||||
pg-protocol: 1.6.1
|
||||
pg-types: 4.0.2
|
||||
|
||||
|
@ -2012,15 +2037,19 @@ snapshots:
|
|||
domhandler: 5.0.3
|
||||
domutils: 3.1.0
|
||||
|
||||
cheerio@1.0.0-rc.12:
|
||||
cheerio@1.0.0:
|
||||
dependencies:
|
||||
cheerio-select: 2.1.0
|
||||
dom-serializer: 2.0.0
|
||||
domhandler: 5.0.3
|
||||
domutils: 3.1.0
|
||||
htmlparser2: 8.0.2
|
||||
encoding-sniffer: 0.2.0
|
||||
htmlparser2: 9.1.0
|
||||
parse5: 7.1.2
|
||||
parse5-htmlparser2-tree-adapter: 7.0.0
|
||||
parse5-parser-stream: 7.1.2
|
||||
undici: 6.19.8
|
||||
whatwg-mimetype: 4.0.0
|
||||
|
||||
chokidar@3.6.0:
|
||||
dependencies:
|
||||
|
@ -2147,6 +2176,11 @@ snapshots:
|
|||
|
||||
encoding-japanese@2.2.0: {}
|
||||
|
||||
encoding-sniffer@0.2.0:
|
||||
dependencies:
|
||||
iconv-lite: 0.6.3
|
||||
whatwg-encoding: 3.1.1
|
||||
|
||||
entities@4.5.0: {}
|
||||
|
||||
error-ex@1.3.2:
|
||||
|
@ -2186,7 +2220,7 @@ snapshots:
|
|||
'@esbuild/win32-ia32': 0.23.1
|
||||
'@esbuild/win32-x64': 0.23.1
|
||||
|
||||
escalade@3.1.2: {}
|
||||
escalade@3.2.0: {}
|
||||
|
||||
escape-string-regexp@1.0.5: {}
|
||||
|
||||
|
@ -2253,7 +2287,7 @@ snapshots:
|
|||
fast-json-stringify: 5.16.1
|
||||
find-my-way: 8.2.0
|
||||
light-my-request: 5.13.0
|
||||
pino: 9.3.2
|
||||
pino: 9.4.0
|
||||
process-warning: 3.0.0
|
||||
proxy-addr: 2.0.7
|
||||
rfdc: 1.4.1
|
||||
|
@ -2347,7 +2381,7 @@ snapshots:
|
|||
graphile-config@0.0.1-beta.9:
|
||||
dependencies:
|
||||
'@types/interpret': 1.1.3
|
||||
'@types/node': 20.16.1
|
||||
'@types/node': 20.16.3
|
||||
'@types/semver': 7.5.8
|
||||
chalk: 4.1.2
|
||||
debug: 4.3.6(supports-color@8.1.1)
|
||||
|
@ -2362,7 +2396,7 @@ snapshots:
|
|||
dependencies:
|
||||
'@graphile/logger': 0.2.0
|
||||
'@types/debug': 4.1.12
|
||||
'@types/pg': 8.11.6
|
||||
'@types/pg': 8.11.8
|
||||
cosmiconfig: 8.3.6(typescript@5.5.4)
|
||||
graphile-config: 0.0.1-beta.9
|
||||
json5: 2.2.3
|
||||
|
@ -2407,6 +2441,13 @@ snapshots:
|
|||
domutils: 3.1.0
|
||||
entities: 4.5.0
|
||||
|
||||
htmlparser2@9.1.0:
|
||||
dependencies:
|
||||
domelementtype: 2.3.0
|
||||
domhandler: 5.0.3
|
||||
domutils: 3.1.0
|
||||
entities: 4.5.0
|
||||
|
||||
human-signals@2.1.0: {}
|
||||
|
||||
iconv-lite@0.6.3:
|
||||
|
@ -2686,6 +2727,10 @@ snapshots:
|
|||
domhandler: 5.0.3
|
||||
parse5: 7.1.2
|
||||
|
||||
parse5-parser-stream@7.1.2:
|
||||
dependencies:
|
||||
parse5: 7.1.2
|
||||
|
||||
parse5@7.1.2:
|
||||
dependencies:
|
||||
entities: 4.5.0
|
||||
|
@ -2757,7 +2802,7 @@ snapshots:
|
|||
dependencies:
|
||||
split2: 4.2.0
|
||||
|
||||
picocolors@1.0.1: {}
|
||||
picocolors@1.1.0: {}
|
||||
|
||||
picomatch@2.3.1: {}
|
||||
|
||||
|
@ -2778,11 +2823,11 @@ snapshots:
|
|||
process-warning: 3.0.0
|
||||
quick-format-unescaped: 4.0.4
|
||||
real-require: 0.2.0
|
||||
safe-stable-stringify: 2.4.3
|
||||
sonic-boom: 4.0.1
|
||||
safe-stable-stringify: 2.5.0
|
||||
sonic-boom: 4.1.0
|
||||
thread-stream: 3.1.0
|
||||
|
||||
pino@9.3.2:
|
||||
pino@9.4.0:
|
||||
dependencies:
|
||||
atomic-sleep: 1.0.0
|
||||
fast-redact: 3.5.0
|
||||
|
@ -2792,8 +2837,8 @@ snapshots:
|
|||
process-warning: 4.0.0
|
||||
quick-format-unescaped: 4.0.4
|
||||
real-require: 0.2.0
|
||||
safe-stable-stringify: 2.4.3
|
||||
sonic-boom: 4.0.1
|
||||
safe-stable-stringify: 2.5.0
|
||||
sonic-boom: 4.1.0
|
||||
thread-stream: 3.1.0
|
||||
|
||||
pirates@4.0.6: {}
|
||||
|
@ -2879,26 +2924,26 @@ snapshots:
|
|||
|
||||
rfdc@1.4.1: {}
|
||||
|
||||
rollup@4.21.0:
|
||||
rollup@4.21.2:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.5
|
||||
optionalDependencies:
|
||||
'@rollup/rollup-android-arm-eabi': 4.21.0
|
||||
'@rollup/rollup-android-arm64': 4.21.0
|
||||
'@rollup/rollup-darwin-arm64': 4.21.0
|
||||
'@rollup/rollup-darwin-x64': 4.21.0
|
||||
'@rollup/rollup-linux-arm-gnueabihf': 4.21.0
|
||||
'@rollup/rollup-linux-arm-musleabihf': 4.21.0
|
||||
'@rollup/rollup-linux-arm64-gnu': 4.21.0
|
||||
'@rollup/rollup-linux-arm64-musl': 4.21.0
|
||||
'@rollup/rollup-linux-powerpc64le-gnu': 4.21.0
|
||||
'@rollup/rollup-linux-riscv64-gnu': 4.21.0
|
||||
'@rollup/rollup-linux-s390x-gnu': 4.21.0
|
||||
'@rollup/rollup-linux-x64-gnu': 4.21.0
|
||||
'@rollup/rollup-linux-x64-musl': 4.21.0
|
||||
'@rollup/rollup-win32-arm64-msvc': 4.21.0
|
||||
'@rollup/rollup-win32-ia32-msvc': 4.21.0
|
||||
'@rollup/rollup-win32-x64-msvc': 4.21.0
|
||||
'@rollup/rollup-android-arm-eabi': 4.21.2
|
||||
'@rollup/rollup-android-arm64': 4.21.2
|
||||
'@rollup/rollup-darwin-arm64': 4.21.2
|
||||
'@rollup/rollup-darwin-x64': 4.21.2
|
||||
'@rollup/rollup-linux-arm-gnueabihf': 4.21.2
|
||||
'@rollup/rollup-linux-arm-musleabihf': 4.21.2
|
||||
'@rollup/rollup-linux-arm64-gnu': 4.21.2
|
||||
'@rollup/rollup-linux-arm64-musl': 4.21.2
|
||||
'@rollup/rollup-linux-powerpc64le-gnu': 4.21.2
|
||||
'@rollup/rollup-linux-riscv64-gnu': 4.21.2
|
||||
'@rollup/rollup-linux-s390x-gnu': 4.21.2
|
||||
'@rollup/rollup-linux-x64-gnu': 4.21.2
|
||||
'@rollup/rollup-linux-x64-musl': 4.21.2
|
||||
'@rollup/rollup-win32-arm64-msvc': 4.21.2
|
||||
'@rollup/rollup-win32-ia32-msvc': 4.21.2
|
||||
'@rollup/rollup-win32-x64-msvc': 4.21.2
|
||||
fsevents: 2.3.3
|
||||
|
||||
run-parallel@1.2.0:
|
||||
|
@ -2911,7 +2956,7 @@ snapshots:
|
|||
dependencies:
|
||||
ret: 0.4.3
|
||||
|
||||
safe-stable-stringify@2.4.3: {}
|
||||
safe-stable-stringify@2.5.0: {}
|
||||
|
||||
safer-buffer@2.1.2: {}
|
||||
|
||||
|
@ -2964,7 +3009,7 @@ snapshots:
|
|||
ip-address: 9.0.5
|
||||
smart-buffer: 4.2.0
|
||||
|
||||
sonic-boom@4.0.1:
|
||||
sonic-boom@4.1.0:
|
||||
dependencies:
|
||||
atomic-sleep: 1.0.0
|
||||
|
||||
|
@ -3067,10 +3112,10 @@ snapshots:
|
|||
execa: 5.1.1
|
||||
globby: 11.1.0
|
||||
joycon: 3.1.1
|
||||
picocolors: 1.0.1
|
||||
picocolors: 1.1.0
|
||||
postcss-load-config: 6.0.1
|
||||
resolve-from: 5.0.0
|
||||
rollup: 4.21.0
|
||||
rollup: 4.21.2
|
||||
source-map: 0.8.0-beta.0
|
||||
sucrase: 3.35.0
|
||||
tree-kill: 1.2.2
|
||||
|
@ -3088,8 +3133,16 @@ snapshots:
|
|||
|
||||
undici-types@6.19.8: {}
|
||||
|
||||
undici@6.19.8: {}
|
||||
|
||||
webidl-conversions@4.0.2: {}
|
||||
|
||||
whatwg-encoding@3.1.1:
|
||||
dependencies:
|
||||
iconv-lite: 0.6.3
|
||||
|
||||
whatwg-mimetype@4.0.0: {}
|
||||
|
||||
whatwg-url@7.1.0:
|
||||
dependencies:
|
||||
lodash.sortby: 4.7.0
|
||||
|
@ -3134,7 +3187,7 @@ snapshots:
|
|||
yargs@16.2.0:
|
||||
dependencies:
|
||||
cliui: 7.0.4
|
||||
escalade: 3.1.2
|
||||
escalade: 3.2.0
|
||||
get-caller-file: 2.0.5
|
||||
require-directory: 2.1.1
|
||||
string-width: 4.2.3
|
||||
|
@ -3144,7 +3197,7 @@ snapshots:
|
|||
yargs@17.7.2:
|
||||
dependencies:
|
||||
cliui: 8.0.1
|
||||
escalade: 3.1.2
|
||||
escalade: 3.2.0
|
||||
get-caller-file: 2.0.5
|
||||
require-directory: 2.1.1
|
||||
string-width: 4.2.3
|
||||
|
|
|
@ -17,7 +17,6 @@ export default defineConfig({
|
|||
* be transpiled / bundled together with the deployed code.
|
||||
*/
|
||||
noExternal: [
|
||||
"@futureporn/image",
|
||||
"@futureporn/utils",
|
||||
"@futureporn/scout",
|
||||
"@futureporn/storage",
|
||||
|
|
|
@ -12,67 +12,67 @@
|
|||
"superclean": "rm -rf node_modules && rm -rf pnpm-lock.yaml && rm -rf dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^6.5.2",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.5.2",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.5.2",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.5.2",
|
||||
"@fortawesome/fontawesome-free": "^6.6.0",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.6.0",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.6.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.6.0",
|
||||
"@fortawesome/react-fontawesome": "^0.2.2",
|
||||
"@futureporn/types": "workspace:*",
|
||||
"@hookform/error-message": "^2.0.1",
|
||||
"@hookform/resolvers": "^3.7.0",
|
||||
"@hookform/resolvers": "^3.9.0",
|
||||
"@mux/blurhash": "^0.1.2",
|
||||
"@mux/mux-player": "^2.7.0",
|
||||
"@mux/mux-player-react": "^2.7.0",
|
||||
"@mux/mux-player": "^2.9.1",
|
||||
"@mux/mux-player-react": "^2.9.1",
|
||||
"@paralleldrive/cuid2": "^2.2.2",
|
||||
"@react-hookz/web": "^24.0.4",
|
||||
"@tanstack/react-query": "^5.49.2",
|
||||
"@tanstack/react-table": "^8.19.2",
|
||||
"@types/lodash": "^4.17.6",
|
||||
"@tanstack/react-query": "^5.53.3",
|
||||
"@tanstack/react-table": "^8.20.5",
|
||||
"@types/lodash": "^4.17.7",
|
||||
"@types/qs": "^6.9.15",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react": "^18.3.5",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@uppy/aws-s3": "^3.6.2",
|
||||
"@uppy/aws-s3-multipart": "^3.12.0",
|
||||
"@uppy/core": "^3.13.0",
|
||||
"@uppy/dashboard": "^3.9.1",
|
||||
"@uppy/drag-drop": "^3.1.0",
|
||||
"@uppy/file-input": "^3.1.2",
|
||||
"@uppy/progress-bar": "^3.1.1",
|
||||
"@uppy/react": "^3.4.0",
|
||||
"@uppy/remote-sources": "^1.3.0",
|
||||
"bulma": "^1.0.1",
|
||||
"date-fns": "^2.30.0",
|
||||
"date-fns-tz": "^2.0.1",
|
||||
"dayjs": "^1.11.11",
|
||||
"@uppy/aws-s3": "^4.1.0",
|
||||
"@uppy/aws-s3-multipart": "^4.0.0",
|
||||
"@uppy/core": "^4.2.0",
|
||||
"@uppy/dashboard": "^4.1.0",
|
||||
"@uppy/drag-drop": "^4.0.2",
|
||||
"@uppy/file-input": "^4.0.1",
|
||||
"@uppy/progress-bar": "^4.0.0",
|
||||
"@uppy/react": "^4.0.2",
|
||||
"@uppy/remote-sources": "^2.2.0",
|
||||
"bulma": "^1.0.2",
|
||||
"date-fns": "^3.6.0",
|
||||
"date-fns-tz": "^3.1.3",
|
||||
"dayjs": "^1.11.13",
|
||||
"feed": "^4.2.2",
|
||||
"gray-matter": "^4.0.3",
|
||||
"hls.js": "^1.5.12",
|
||||
"hls.js": "^1.5.15",
|
||||
"lodash": "^4.17.21",
|
||||
"lunarphase-js": "^2.0.3",
|
||||
"multiformats": "^13.1.3",
|
||||
"next": "14.0.4",
|
||||
"multiformats": "^13.2.2",
|
||||
"next": "14.2.7",
|
||||
"next-goatcounter": "^1.0.5",
|
||||
"nextjs-toploader": "^1.6.12",
|
||||
"nextjs-toploader": "^3.6.15",
|
||||
"plyr": "^3.7.8",
|
||||
"prism-react-renderer": "^2.3.1",
|
||||
"qs": "^6.12.2",
|
||||
"prism-react-renderer": "^2.4.0",
|
||||
"qs": "^6.13.0",
|
||||
"react": "^18.3.1",
|
||||
"react-data-table-component": "^7.6.2",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-hook-form": "^7.52.1",
|
||||
"react-hook-form": "^7.53.0",
|
||||
"react-loading-skeleton": "^3.4.0",
|
||||
"react-toastify": "^9.1.3",
|
||||
"react-toastify": "^10.0.5",
|
||||
"sass": "^1.77.8",
|
||||
"sharp": "^0.33.4",
|
||||
"sharp": "^0.33.5",
|
||||
"slugify": "^1.6.6",
|
||||
"styled-components": "5.3.3",
|
||||
"@futureporn/types": "workspace:*",
|
||||
"styled-components": "6.1.13",
|
||||
"yup": "^1.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.14.9",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-next": "14.0.4",
|
||||
"typescript": "5.3.3"
|
||||
"@types/node": "^22.5.2",
|
||||
"eslint": "^9.9.1",
|
||||
"eslint-config-next": "14.2.7",
|
||||
"typescript": "5.5.4"
|
||||
},
|
||||
"packageManager": "pnpm@9.1.3"
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -33,9 +33,9 @@
|
|||
"@temporalio/workflow": "^1.11.1",
|
||||
"@tsconfig/node20": "^20.1.4",
|
||||
"@types/imapflow": "^1.0.19",
|
||||
"@types/node": "^22.5.0",
|
||||
"@types/pg": "^8.11.6",
|
||||
"cheerio": "1.0.0-rc.12",
|
||||
"@types/node": "^22.5.2",
|
||||
"@types/pg": "^8.11.8",
|
||||
"cheerio": "1.0.0",
|
||||
"concurrently": "^8.2.2",
|
||||
"date-fns": "^3.6.0",
|
||||
"dotenv": "^16.4.5",
|
||||
|
@ -45,13 +45,13 @@
|
|||
"htmlparser2": "^9.1.0",
|
||||
"imapflow": "^1.0.164",
|
||||
"js-yaml": "^4.1.0",
|
||||
"limiter": "2.0.1",
|
||||
"limiter": "2.1.0",
|
||||
"mailparser": "^3.7.1",
|
||||
"node-fetch": "^3.3.2",
|
||||
"openapi-backend": "^5.10.6",
|
||||
"p-retry": "^5.1.2",
|
||||
"pg": "8.8.0",
|
||||
"prevvy": "^7.5.0",
|
||||
"p-retry": "^6.2.0",
|
||||
"pg": "8.12.0",
|
||||
"prevvy": "^8.0.1",
|
||||
"qs": "^6.13.0",
|
||||
"rate-limiter-flexible": "^5.0.3",
|
||||
"sharp": "^0.33.5",
|
||||
|
@ -59,7 +59,7 @@
|
|||
"swagger-editor-dist": "^4.13.1",
|
||||
"swagger-ui-dist": "^5.17.14",
|
||||
"ts-json-schema-generator": "^2.3.0",
|
||||
"tsx": "^4.18.0",
|
||||
"tsx": "^4.19.0",
|
||||
"typescript-json-schema": "^0.65.1",
|
||||
"xpath": "^0.0.34"
|
||||
},
|
||||
|
@ -68,7 +68,7 @@
|
|||
"@babel/preset-env": "^7.25.4",
|
||||
"@babel/preset-typescript": "^7.24.7",
|
||||
"@futureporn/utils": "workspace:^",
|
||||
"@types/chai": "^4.3.18",
|
||||
"@types/chai": "^4.3.19",
|
||||
"@types/cheerio": "^0.22.35",
|
||||
"@types/mailparser": "^3.4.4",
|
||||
"@types/mocha": "^10.0.7",
|
||||
|
@ -77,7 +77,7 @@
|
|||
"esmock": "^2.6.7",
|
||||
"mocha": "^10.7.3",
|
||||
"nodemon": "^3.1.4",
|
||||
"sinon": "^15.2.0",
|
||||
"sinon": "^18.0.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsup": "^8.2.4",
|
||||
"typescript": "^5.5.4"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
import { download, getTmpFile } from '@futureporn/utils';
|
||||
import { download, getTmpFile } from '@futureporn/utils/file.ts';
|
||||
import type { VtuberRecord } from '@futureporn/types';
|
||||
import { ua0 } from './ua.ts';
|
||||
import scrapingFetch from './scrapingFetch.ts';
|
||||
|
|
|
@ -11,7 +11,7 @@ import { VtuberRecord, VtuberResponse, VtuberDataScrape } from './schemas.ts'
|
|||
import scrapeVtuberData from './scrapeVtuberData.ts'
|
||||
import { getPlaylistUrl } from './ytdlp.ts'
|
||||
import { getRandomRoom } from './cb.ts'
|
||||
import { getPackageVersion } from '@futureporn/utils'
|
||||
import { getPackageVersion } from '@futureporn/utils/file.ts'
|
||||
|
||||
|
||||
type VtuberDataRequest = FastifyRequest<{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
import * as htmlparser2 from "htmlparser2";
|
||||
import { load } from 'cheerio'
|
||||
import { download } from '@futureporn/utils';
|
||||
import { download } from '@futureporn/utils/file.ts';
|
||||
import pRetry, { AbortError } from 'p-retry';
|
||||
|
||||
if (!process.env.SCOUT_NITTER_ACCESS_KEY) throw new Error('SCOUT_NITTER_ACCESS_KEY was undefined in env');
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue