yt-transcript-strapi-plugin 0.0.14 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/package.json +21 -8
  2. package/dist/_chunks/en-B4KWt_jN.js +0 -5
  3. package/dist/_chunks/en-B4KWt_jN.js.map +0 -1
  4. package/dist/_chunks/en-Byx4XI2L.mjs +0 -5
  5. package/dist/_chunks/en-Byx4XI2L.mjs.map +0 -1
  6. package/dist/admin/index.js +0 -58
  7. package/dist/admin/index.js.map +0 -1
  8. package/dist/admin/index.mjs +0 -59
  9. package/dist/admin/index.mjs.map +0 -1
  10. package/dist/admin/src/components/Initializer.d.ts +0 -5
  11. package/dist/admin/src/components/PluginIcon.d.ts +0 -2
  12. package/dist/admin/src/index.d.ts +0 -11
  13. package/dist/admin/src/pages/App.d.ts +0 -2
  14. package/dist/admin/src/pages/HomePage.d.ts +0 -2
  15. package/dist/admin/src/pluginId.d.ts +0 -1
  16. package/dist/admin/src/utils/getTranslation.d.ts +0 -2
  17. package/dist/server/index.js +0 -294
  18. package/dist/server/index.js.map +0 -1
  19. package/dist/server/index.mjs +0 -273
  20. package/dist/server/index.mjs.map +0 -1
  21. package/dist/server/src/bootstrap.d.ts +0 -5
  22. package/dist/server/src/config/index.d.ts +0 -5
  23. package/dist/server/src/content-types/index.d.ts +0 -42
  24. package/dist/server/src/content-types/transcript/index.d.ts +0 -40
  25. package/dist/server/src/controllers/controller.d.ts +0 -13
  26. package/dist/server/src/controllers/index.d.ts +0 -14
  27. package/dist/server/src/destroy.d.ts +0 -5
  28. package/dist/server/src/index.d.ts +0 -109
  29. package/dist/server/src/middlewares/index.d.ts +0 -2
  30. package/dist/server/src/policies/index.d.ts +0 -2
  31. package/dist/server/src/register.d.ts +0 -5
  32. package/dist/server/src/routes/admin.d.ts +0 -9
  33. package/dist/server/src/routes/content-api.d.ts +0 -9
  34. package/dist/server/src/routes/index.d.ts +0 -25
  35. package/dist/server/src/services/index.d.ts +0 -14
  36. package/dist/server/src/services/service.d.ts +0 -14
  37. package/dist/server/src/utils/extract-youtube-id.d.ts +0 -1
  38. package/dist/server/src/utils/fetch-transcript.d.ts +0 -13
  39. package/dist/server/src/utils/openai.d.ts +0 -9
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.0.14",
2
+ "version": "0.0.15",
3
3
  "keywords": [
4
4
  "yt-transcript-strapi-plugin",
5
5
  "youtube",
@@ -45,16 +45,21 @@
45
45
  "@langchain/core": "^0.3.18",
46
46
  "@langchain/openai": "^0.3.14",
47
47
  "@langchain/textsplitters": "^0.1.0",
48
+ "@modelcontextprotocol/sdk": "^1.12.0",
48
49
  "@strapi/design-system": "^2.0.0-rc.12",
49
50
  "@strapi/icons": "^2.0.0-rc.12",
50
51
  "langchain": "^0.3.5",
51
52
  "react-intl": "^6.8.7",
52
- "youtubei.js": "^11.0.1"
53
+ "zod": "^3.23.0"
53
54
  },
55
+ "bundledDependencies": [
56
+ "@modelcontextprotocol/sdk",
57
+ "zod"
58
+ ],
54
59
  "devDependencies": {
55
- "@strapi/sdk-plugin": "^5.2.7",
56
- "@strapi/strapi": "^5.0.0-rc.30",
57
- "@strapi/typescript-utils": "^5.0.0-rc.30",
60
+ "@strapi/sdk-plugin": "^5.3.2",
61
+ "@strapi/strapi": "^5.33.0",
62
+ "@strapi/typescript-utils": "^5.33.0",
58
63
  "@types/react": "^18.3.12",
59
64
  "@types/react-dom": "^18.3.1",
60
65
  "prettier": "^3.3.3",
@@ -65,13 +70,17 @@
65
70
  "typescript": "^5.6.3"
66
71
  },
67
72
  "peerDependencies": {
68
- "@strapi/sdk-plugin": "^5.2.7",
69
- "@strapi/strapi": "^5.0.0-rc.30",
73
+ "@strapi/sdk-plugin": "^5.3.2",
74
+ "@strapi/strapi": "^5.33.0",
70
75
  "react": "^18.3.1",
71
76
  "react-dom": "^18.3.1",
72
77
  "react-router-dom": "^6.28.0",
73
78
  "styled-components": "^6.1.13"
74
79
  },
80
+ "engines": {
81
+ "node": ">=18.0.0 <=24.x.x",
82
+ "npm": ">=6.0.0"
83
+ },
75
84
  "strapi": {
76
85
  "kind": "plugin",
77
86
  "name": "yt-transcript-strapi-plugin",
@@ -84,5 +93,9 @@
84
93
  "author": "Paul Brats <codingafterthirty@gmail.com>",
85
94
  "publishConfig": {
86
95
  "access": "public"
87
- }
96
+ },
97
+ "bundleDependencies": [
98
+ "@modelcontextprotocol/sdk",
99
+ "zod"
100
+ ]
88
101
  }
@@ -1,5 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const en = {};
4
- exports.default = en;
5
- //# sourceMappingURL=en-B4KWt_jN.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"en-B4KWt_jN.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -1,5 +0,0 @@
1
- const en = {};
2
- export {
3
- en as default
4
- };
5
- //# sourceMappingURL=en-Byx4XI2L.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"en-Byx4XI2L.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -1,58 +0,0 @@
1
- "use strict";
2
- const react = require("react");
3
- const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
4
- const v = glob[path];
5
- if (v) {
6
- return typeof v === "function" ? v() : Promise.resolve(v);
7
- }
8
- return new Promise((_, reject) => {
9
- (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
10
- reject.bind(
11
- null,
12
- new Error(
13
- "Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
14
- )
15
- )
16
- );
17
- });
18
- };
19
- const PLUGIN_ID = "yt-transcript-strapi-plugin";
20
- const getTranslation = (id) => `${PLUGIN_ID}.${id}`;
21
- const Initializer = ({ setPlugin }) => {
22
- const ref = react.useRef(setPlugin);
23
- react.useEffect(() => {
24
- ref.current(PLUGIN_ID);
25
- }, []);
26
- return null;
27
- };
28
- const index = {
29
- register(app) {
30
- app.registerPlugin({
31
- id: PLUGIN_ID,
32
- initializer: Initializer,
33
- isReady: false,
34
- name: PLUGIN_ID
35
- });
36
- },
37
- async registerTrads(app) {
38
- const { locales } = app;
39
- const importedTranslations = await Promise.all(
40
- locales.map((locale) => {
41
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => Promise.resolve().then(() => require("../_chunks/en-B4KWt_jN.js")) }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
42
- return {
43
- data: getTranslation(data),
44
- locale
45
- };
46
- }).catch(() => {
47
- return {
48
- data: {},
49
- locale
50
- };
51
- });
52
- })
53
- );
54
- return importedTranslations;
55
- }
56
- };
57
- module.exports = index;
58
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":["../../admin/src/pluginId.ts","../../admin/src/utils/getTranslation.ts","../../admin/src/components/Initializer.tsx","../../admin/src/index.ts"],"sourcesContent":["export const PLUGIN_ID = 'yt-transcript-strapi-plugin';\n","import { PLUGIN_ID } from '../pluginId';\n\nconst getTranslation = (id: string) => `${PLUGIN_ID}.${id}`;\n\nexport { getTranslation };\n","import { useEffect, useRef } from 'react';\n\nimport { PLUGIN_ID } from '../pluginId';\n\ntype InitializerProps = {\n setPlugin: (id: string) => void;\n};\n\nconst Initializer = ({ setPlugin }: InitializerProps) => {\n const ref = useRef(setPlugin);\n\n useEffect(() => {\n ref.current(PLUGIN_ID);\n }, []);\n\n return null;\n};\n\nexport { Initializer };\n","import { getTranslation } from './utils/getTranslation';\nimport { PLUGIN_ID } from './pluginId';\nimport { Initializer } from './components/Initializer';\n// import { PluginIcon } from './components/PluginIcon';\n\nexport default {\n register(app: any) {\n // app.addMenuLink({\n // to: `plugins/${PLUGIN_ID}`,\n // icon: PluginIcon,\n // intlLabel: {\n // id: `${PLUGIN_ID}.plugin.name`,\n // defaultMessage: PLUGIN_ID,\n // },\n // Component: async () => {\n // const { App } = await import('./pages/App');\n\n // return App;\n // },\n // });\n\n app.registerPlugin({\n id: PLUGIN_ID,\n initializer: Initializer,\n isReady: false,\n name: PLUGIN_ID,\n });\n },\n\n async registerTrads(app: any) {\n const { locales } = app;\n\n const importedTranslations = await Promise.all(\n (locales as string[]).map((locale) => {\n return import(`./translations/${locale}.json`)\n .then(({ default: data }) => {\n return {\n data: getTranslation(data),\n locale,\n };\n })\n .catch(() => {\n return {\n data: {},\n locale,\n };\n });\n })\n );\n\n return importedTranslations;\n },\n};\n"],"names":["useRef","useEffect"],"mappings":";;;;;;;;;;;;;;;;;;AAAO,MAAM,YAAY;ACEzB,MAAM,iBAAiB,CAAC,OAAe,GAAG,SAAS,IAAI,EAAE;ACMzD,MAAM,cAAc,CAAC,EAAE,gBAAkC;AACjD,QAAA,MAAMA,aAAO,SAAS;AAE5BC,QAAAA,UAAU,MAAM;AACd,QAAI,QAAQ,SAAS;AAAA,EACvB,GAAG,EAAE;AAEE,SAAA;AACT;ACXA,MAAe,QAAA;AAAA,EACb,SAAS,KAAU;AAejB,QAAI,eAAe;AAAA,MACjB,IAAI;AAAA,MACJ,aAAa;AAAA,MACb,SAAS;AAAA,MACT,MAAM;AAAA,IAAA,CACP;AAAA,EACH;AAAA,EAEA,MAAM,cAAc,KAAU;AACtB,UAAA,EAAE,YAAY;AAEd,UAAA,uBAAuB,MAAM,QAAQ;AAAA,MACxC,QAAqB,IAAI,CAAC,WAAW;AAC7B,eAAA,qCAA+B,uBAAA,OAAA,EAAA,0BAAA,MAAA,QAAA,QAAA,EAAA,KAAA,MAAA,QAAA,2BAAA,CAAA,EAAA,CAAA,GAAA,kBAAA,MAAA,SAAA,CAAA,EACnC,KAAK,CAAC,EAAE,SAAS,WAAW;AACpB,iBAAA;AAAA,YACL,MAAM,eAAe,IAAI;AAAA,YACzB;AAAA,UACF;AAAA,QAAA,CACD,EACA,MAAM,MAAM;AACJ,iBAAA;AAAA,YACL,MAAM,CAAC;AAAA,YACP;AAAA,UACF;AAAA,QAAA,CACD;AAAA,MACJ,CAAA;AAAA,IACH;AAEO,WAAA;AAAA,EAAA;AAEX;;"}
@@ -1,59 +0,0 @@
1
- import { useRef, useEffect } from "react";
2
- const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
3
- const v = glob[path];
4
- if (v) {
5
- return typeof v === "function" ? v() : Promise.resolve(v);
6
- }
7
- return new Promise((_, reject) => {
8
- (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
9
- reject.bind(
10
- null,
11
- new Error(
12
- "Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
13
- )
14
- )
15
- );
16
- });
17
- };
18
- const PLUGIN_ID = "yt-transcript-strapi-plugin";
19
- const getTranslation = (id) => `${PLUGIN_ID}.${id}`;
20
- const Initializer = ({ setPlugin }) => {
21
- const ref = useRef(setPlugin);
22
- useEffect(() => {
23
- ref.current(PLUGIN_ID);
24
- }, []);
25
- return null;
26
- };
27
- const index = {
28
- register(app) {
29
- app.registerPlugin({
30
- id: PLUGIN_ID,
31
- initializer: Initializer,
32
- isReady: false,
33
- name: PLUGIN_ID
34
- });
35
- },
36
- async registerTrads(app) {
37
- const { locales } = app;
38
- const importedTranslations = await Promise.all(
39
- locales.map((locale) => {
40
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("../_chunks/en-Byx4XI2L.mjs") }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
41
- return {
42
- data: getTranslation(data),
43
- locale
44
- };
45
- }).catch(() => {
46
- return {
47
- data: {},
48
- locale
49
- };
50
- });
51
- })
52
- );
53
- return importedTranslations;
54
- }
55
- };
56
- export {
57
- index as default
58
- };
59
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs","sources":["../../admin/src/pluginId.ts","../../admin/src/utils/getTranslation.ts","../../admin/src/components/Initializer.tsx","../../admin/src/index.ts"],"sourcesContent":["export const PLUGIN_ID = 'yt-transcript-strapi-plugin';\n","import { PLUGIN_ID } from '../pluginId';\n\nconst getTranslation = (id: string) => `${PLUGIN_ID}.${id}`;\n\nexport { getTranslation };\n","import { useEffect, useRef } from 'react';\n\nimport { PLUGIN_ID } from '../pluginId';\n\ntype InitializerProps = {\n setPlugin: (id: string) => void;\n};\n\nconst Initializer = ({ setPlugin }: InitializerProps) => {\n const ref = useRef(setPlugin);\n\n useEffect(() => {\n ref.current(PLUGIN_ID);\n }, []);\n\n return null;\n};\n\nexport { Initializer };\n","import { getTranslation } from './utils/getTranslation';\nimport { PLUGIN_ID } from './pluginId';\nimport { Initializer } from './components/Initializer';\n// import { PluginIcon } from './components/PluginIcon';\n\nexport default {\n register(app: any) {\n // app.addMenuLink({\n // to: `plugins/${PLUGIN_ID}`,\n // icon: PluginIcon,\n // intlLabel: {\n // id: `${PLUGIN_ID}.plugin.name`,\n // defaultMessage: PLUGIN_ID,\n // },\n // Component: async () => {\n // const { App } = await import('./pages/App');\n\n // return App;\n // },\n // });\n\n app.registerPlugin({\n id: PLUGIN_ID,\n initializer: Initializer,\n isReady: false,\n name: PLUGIN_ID,\n });\n },\n\n async registerTrads(app: any) {\n const { locales } = app;\n\n const importedTranslations = await Promise.all(\n (locales as string[]).map((locale) => {\n return import(`./translations/${locale}.json`)\n .then(({ default: data }) => {\n return {\n data: getTranslation(data),\n locale,\n };\n })\n .catch(() => {\n return {\n data: {},\n locale,\n };\n });\n })\n );\n\n return importedTranslations;\n },\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAO,MAAM,YAAY;ACEzB,MAAM,iBAAiB,CAAC,OAAe,GAAG,SAAS,IAAI,EAAE;ACMzD,MAAM,cAAc,CAAC,EAAE,gBAAkC;AACjD,QAAA,MAAM,OAAO,SAAS;AAE5B,YAAU,MAAM;AACd,QAAI,QAAQ,SAAS;AAAA,EACvB,GAAG,EAAE;AAEE,SAAA;AACT;ACXA,MAAe,QAAA;AAAA,EACb,SAAS,KAAU;AAejB,QAAI,eAAe;AAAA,MACjB,IAAI;AAAA,MACJ,aAAa;AAAA,MACb,SAAS;AAAA,MACT,MAAM;AAAA,IAAA,CACP;AAAA,EACH;AAAA,EAEA,MAAM,cAAc,KAAU;AACtB,UAAA,EAAE,YAAY;AAEd,UAAA,uBAAuB,MAAM,QAAQ;AAAA,MACxC,QAAqB,IAAI,CAAC,WAAW;AAC7B,eAAA,qCAA+B,uBAAA,OAAA,EAAA,0BAAA,MAAA,OAAA,4BAAA,EAAA,CAAA,GAAA,kBAAA,MAAA,SAAA,CAAA,EACnC,KAAK,CAAC,EAAE,SAAS,WAAW;AACpB,iBAAA;AAAA,YACL,MAAM,eAAe,IAAI;AAAA,YACzB;AAAA,UACF;AAAA,QAAA,CACD,EACA,MAAM,MAAM;AACJ,iBAAA;AAAA,YACL,MAAM,CAAC;AAAA,YACP;AAAA,UACF;AAAA,QAAA,CACD;AAAA,MACJ,CAAA;AAAA,IACH;AAEO,WAAA;AAAA,EAAA;AAEX;"}
@@ -1,5 +0,0 @@
1
- type InitializerProps = {
2
- setPlugin: (id: string) => void;
3
- };
4
- declare const Initializer: ({ setPlugin }: InitializerProps) => null;
5
- export { Initializer };
@@ -1,2 +0,0 @@
1
- declare const PluginIcon: () => import("react/jsx-runtime").JSX.Element;
2
- export { PluginIcon };
@@ -1,11 +0,0 @@
1
- declare const _default: {
2
- register(app: any): void;
3
- registerTrads(app: any): Promise<({
4
- data: string;
5
- locale: string;
6
- } | {
7
- data: {};
8
- locale: string;
9
- })[]>;
10
- };
11
- export default _default;
@@ -1,2 +0,0 @@
1
- declare const App: () => import("react/jsx-runtime").JSX.Element;
2
- export { App };
@@ -1,2 +0,0 @@
1
- declare const HomePage: () => import("react/jsx-runtime").JSX.Element;
2
- export { HomePage };
@@ -1 +0,0 @@
1
- export declare const PLUGIN_ID = "yt-transcript-strapi-plugin";
@@ -1,2 +0,0 @@
1
- declare const getTranslation: (id: string) => string;
2
- export { getTranslation };
@@ -1,294 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") {
10
- for (let key of __getOwnPropNames(from))
11
- if (!__hasOwnProp.call(to, key) && key !== except)
12
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
- }
14
- return to;
15
- };
16
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
- // If the importer is in node compatibility mode or this is not an ESM
18
- // file that has been converted to a CommonJS file using a Babel-
19
- // compatible transform (i.e. "__esModule" has not been set), then set
20
- // "default" to the CommonJS "module.exports" for node compatibility.
21
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
- mod
23
- ));
24
- const textsplitters = require("@langchain/textsplitters");
25
- const prompts = require("@langchain/core/prompts");
26
- const openai = require("@langchain/openai");
27
- const bootstrap = ({ strapi: strapi2 }) => {
28
- };
29
- const destroy = ({ strapi: strapi2 }) => {
30
- };
31
- const register = ({ strapi: strapi2 }) => {
32
- };
33
- const config = {
34
- default: {},
35
- validator() {
36
- }
37
- };
38
- const kind = "collectionType";
39
- const collectionName = "transcript";
40
- const info = {
41
- singularName: "transcript",
42
- pluralName: "transcripts",
43
- displayName: "Transcript"
44
- };
45
- const options = {
46
- draftAndPublish: false
47
- };
48
- const pluginOptions = {
49
- "content-manager": {
50
- visible: true
51
- },
52
- "content-type-builder": {
53
- visible: true
54
- }
55
- };
56
- const attributes = {
57
- title: {
58
- type: "string"
59
- },
60
- videoId: {
61
- type: "string"
62
- },
63
- fullTranscript: {
64
- type: "richtext"
65
- },
66
- transcriptWithTimeCodes: {
67
- type: "json"
68
- },
69
- readableTranscript: {
70
- type: "richtext"
71
- }
72
- };
73
- const schema = {
74
- kind,
75
- collectionName,
76
- info,
77
- options,
78
- pluginOptions,
79
- attributes
80
- };
81
- const transcript = {
82
- schema
83
- };
84
- const contentTypes = {
85
- transcript
86
- };
87
- function extractYouTubeID(urlOrID) {
88
- const regExpID = /^[a-zA-Z0-9_-]{11}$/;
89
- if (regExpID.test(urlOrID)) {
90
- return urlOrID;
91
- }
92
- const regExpStandard = /youtube\.com\/watch\?v=([a-zA-Z0-9_-]+)/;
93
- const regExpShorts = /youtube\.com\/shorts\/([a-zA-Z0-9_-]+)/;
94
- const matchStandard = urlOrID.match(regExpStandard);
95
- if (matchStandard) {
96
- return matchStandard[1];
97
- }
98
- const matchShorts = urlOrID.match(regExpShorts);
99
- if (matchShorts) {
100
- return matchShorts[1];
101
- }
102
- return null;
103
- }
104
- const controller = ({ strapi: strapi2 }) => ({
105
- async getTranscript(ctx) {
106
- const videoId = extractYouTubeID(ctx.params.videoId);
107
- if (!videoId) return ctx.body = { error: "Invalid YouTube URL or ID", data: null };
108
- console.log("Looking for transcript in database");
109
- const found = await strapi2.plugin("yt-transcript-strapi-plugin").service("service").findTranscript(videoId);
110
- if (found) {
111
- console.log("Transcript found.");
112
- return ctx.body = { data: found };
113
- }
114
- console.log("Transcript not found. Fetching new transcript.");
115
- const transcriptData = await strapi2.plugin("yt-transcript-strapi-plugin").service("service").getTranscript(videoId);
116
- console.log("New transcript fetched.");
117
- const readableTranscript = await strapi2.plugin("yt-transcript-strapi-plugin").service("service").generateHumanReadableTranscript(transcriptData.fullTranscript);
118
- console.log("Human readable transcript generated.");
119
- const payload = {
120
- videoId,
121
- title: transcriptData?.title || "No title found",
122
- fullTranscript: transcriptData?.fullTranscript,
123
- transcriptWithTimeCodes: transcriptData?.transcriptWithTimeCodes,
124
- readableTranscript
125
- };
126
- console.log("Payload:", payload);
127
- console.log("Saving new transcript to database.");
128
- const transcript2 = await strapi2.plugin("yt-transcript-strapi-plugin").service("service").saveTranscript(payload);
129
- ctx.body = { data: transcript2 };
130
- }
131
- });
132
- const controllers = {
133
- controller
134
- };
135
- const middlewares = {};
136
- const policies = {};
137
- const contentApi = [
138
- {
139
- method: "GET",
140
- path: "/yt-transcript/:videoId",
141
- handler: "controller.getTranscript",
142
- config: {
143
- policies: []
144
- }
145
- }
146
- ];
147
- const admin = [
148
- {
149
- method: "GET",
150
- path: "/yt-transcript/:videoId",
151
- handler: "controller.getTranscript",
152
- config: {
153
- policies: []
154
- }
155
- }
156
- ];
157
- const routes = {
158
- "content-api": {
159
- type: "content-api",
160
- routes: [...contentApi]
161
- },
162
- admin: {
163
- type: "admin",
164
- routes: [...admin]
165
- }
166
- };
167
- async function initializeModel({
168
- openAIApiKey,
169
- model,
170
- temp
171
- }) {
172
- return new openai.ChatOpenAI({
173
- temperature: temp,
174
- openAIApiKey,
175
- modelName: model,
176
- maxTokens: 1e3
177
- });
178
- }
179
- const fetchTranscript = async (videoId) => {
180
- console.log("Fetching Transcript - Calling fetchTranscript Utils");
181
- const { Innertube } = await import("youtubei.js");
182
- console.log("Creating YouTube instance");
183
- const youtube = await Innertube.create({
184
- lang: "en",
185
- location: "US",
186
- retrieve_player: false
187
- });
188
- try {
189
- const info2 = await youtube.getInfo(videoId);
190
- const transcriptData = await info2.getTranscript();
191
- console.log("Transcript data fetched");
192
- const transcriptWithTimeCodes = transcriptData?.transcript?.content?.body?.initial_segments.map((segment) => {
193
- const segmentDuration = Number(segment.end_ms) - Number(segment.start_ms);
194
- return {
195
- text: segment.snippet.text,
196
- start: Number(segment.start_ms),
197
- end: Number(segment.end_ms),
198
- duration: segmentDuration
199
- };
200
- });
201
- console.log("Transcript with time codes generated");
202
- const fullTranscript = transcriptData?.transcript?.content?.body?.initial_segments.map((segment) => segment.snippet.text).join(" ");
203
- console.log(fullTranscript, "full transcript");
204
- console.log("Full transcript generated");
205
- console.log("Returning transcript data");
206
- return {
207
- videoId,
208
- fullTranscript,
209
- transcriptWithTimeCodes
210
- };
211
- } catch (error) {
212
- console.error("Error fetching transcript:", error);
213
- throw error;
214
- }
215
- };
216
- async function processTextChunks(chunks, model) {
217
- const punctuationPrompt = prompts.PromptTemplate.fromTemplate(
218
- "Add proper punctuation and capitalization to the following text chunk:\n\n{chunk}"
219
- );
220
- const punctuationChain = punctuationPrompt.pipe(model);
221
- const processedChunks = await Promise.all(
222
- chunks.map(async (chunk) => {
223
- const result = await punctuationChain.invoke({ chunk });
224
- return result.content;
225
- })
226
- );
227
- return processedChunks.join(" ");
228
- }
229
- async function generateModifiedTranscript(rawTranscript) {
230
- const pluginSettings = await strapi.config.get("plugin::yt-transcript-strapi-plugin");
231
- if (!pluginSettings.openAIApiKey || !pluginSettings.model || !pluginSettings.temp || !pluginSettings.maxTokens) {
232
- throw new Error("Missing required configuration for YTTranscript");
233
- }
234
- const chatModel = await initializeModel({
235
- openAIApiKey: pluginSettings.openAIApiKey,
236
- model: pluginSettings.model,
237
- temp: pluginSettings.temp,
238
- maxTokens: pluginSettings.maxTokens
239
- });
240
- const splitter = new textsplitters.TokenTextSplitter({
241
- chunkSize: 1e3,
242
- chunkOverlap: 200
243
- });
244
- const transcriptChunks = await splitter.createDocuments([rawTranscript]);
245
- const chunkTexts = transcriptChunks.map((chunk) => chunk.pageContent);
246
- const modifiedTranscript = await processTextChunks(chunkTexts, chatModel);
247
- return modifiedTranscript;
248
- }
249
- const service = ({ strapi: strapi2 }) => ({
250
- async getTranscript(identifier) {
251
- console.log("Fetching Transcript - Calling fetchTranscript Service");
252
- const youtubeIdRegex = /^[a-zA-Z0-9_-]{11}$/;
253
- const isValid = youtubeIdRegex.test(identifier);
254
- if (!isValid) return { error: "Invalid video ID", data: null };
255
- const transcriptData = await fetchTranscript(identifier);
256
- return transcriptData;
257
- },
258
- async saveTranscript(payload) {
259
- return await strapi2.documents("plugin::yt-transcript-strapi-plugin.transcript").create({
260
- data: payload
261
- });
262
- },
263
- async findTranscript(videoId) {
264
- console.log("Finding transcript for videoId:", videoId);
265
- const transcriptData = await strapi2.documents("plugin::yt-transcript-strapi-plugin.transcript").findFirst({
266
- filters: { videoId }
267
- });
268
- console.log("Transcript found:", transcriptData?.title, "found");
269
- if (!transcriptData) return null;
270
- return transcriptData;
271
- },
272
- async generateHumanReadableTranscript(transcript2) {
273
- console.log("Generating human readable transcript:");
274
- const modifiedTranscript = await generateModifiedTranscript(transcript2);
275
- return modifiedTranscript;
276
- }
277
- });
278
- const services = {
279
- service
280
- };
281
- const index = {
282
- register,
283
- bootstrap,
284
- destroy,
285
- config,
286
- controllers,
287
- routes,
288
- services,
289
- contentTypes,
290
- policies,
291
- middlewares
292
- };
293
- module.exports = index;
294
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":["../../server/src/bootstrap.ts","../../server/src/destroy.ts","../../server/src/register.ts","../../server/src/config/index.ts","../../server/src/content-types/transcript/index.ts","../../server/src/content-types/index.ts","../../server/src/utils/extract-youtube-id.ts","../../server/src/controllers/controller.ts","../../server/src/controllers/index.ts","../../server/src/middlewares/index.ts","../../server/src/policies/index.ts","../../server/src/routes/content-api.ts","../../server/src/routes/admin.ts","../../server/src/routes/index.ts","../../server/src/utils/openai.ts","../../server/src/utils/fetch-transcript.ts","../../server/src/services/service.ts","../../server/src/services/index.ts","../../server/src/index.ts"],"sourcesContent":["import type { Core } from '@strapi/strapi';\n\nconst bootstrap = ({ strapi }: { strapi: Core.Strapi }) => {\n // bootstrap phase\n};\n\nexport default bootstrap;\n","import type { Core } from '@strapi/strapi';\n\nconst destroy = ({ strapi }: { strapi: Core.Strapi }) => {\n // destroy phase\n};\n\nexport default destroy;\n","import type { Core } from '@strapi/strapi';\n\nconst register = ({ strapi }: { strapi: Core.Strapi }) => {\n // register phase\n};\n\nexport default register;\n","export default {\n default: {},\n validator() {},\n};\n","import schema from './schema.json';\n\nexport default {\n schema,\n};","import transcript from './transcript';\n\nexport default {\n transcript,\n};\n\n\n","export function extractYouTubeID(urlOrID: string): string | null {\n // Regular expression for YouTube ID format\n const regExpID = /^[a-zA-Z0-9_-]{11}$/;\n\n // Check if the input is a YouTube ID\n if (regExpID.test(urlOrID)) {\n return urlOrID;\n }\n\n // Regular expression for standard YouTube links\n const regExpStandard = /youtube\\.com\\/watch\\?v=([a-zA-Z0-9_-]+)/;\n\n // Regular expression for YouTube Shorts links\n const regExpShorts = /youtube\\.com\\/shorts\\/([a-zA-Z0-9_-]+)/;\n\n // Check for standard YouTube link\n const matchStandard = urlOrID.match(regExpStandard);\n if (matchStandard) {\n return matchStandard[1];\n }\n\n // Check for YouTube Shorts link\n const matchShorts = urlOrID.match(regExpShorts);\n if (matchShorts) {\n return matchShorts[1];\n }\n\n // Return null if no match is found\n return null;\n}","import type { Core } from '@strapi/strapi';\nimport { extractYouTubeID } from '../utils/extract-youtube-id';\nconst controller = ({ strapi }: { strapi: Core.Strapi }) => ({\n async getTranscript(ctx) {\n const videoId = extractYouTubeID(ctx.params.videoId);\n\n if (!videoId) return (ctx.body = { error: 'Invalid YouTube URL or ID', data: null });\n\n console.log(\"Looking for transcript in database\");\n\n const found = await strapi\n .plugin('yt-transcript-strapi-plugin')\n .service('service')\n .findTranscript(videoId);\n\n if (found) {\n console.log(\"Transcript found.\");\n return (ctx.body = { data: found });\n }\n\n console.log(\"Transcript not found. Fetching new transcript.\");\n\n const transcriptData = await strapi\n .plugin('yt-transcript-strapi-plugin')\n .service('service')\n .getTranscript(videoId);\n\n console.log(\"New transcript fetched.\");\n\n const readableTranscript = await strapi\n .plugin('yt-transcript-strapi-plugin')\n .service('service')\n .generateHumanReadableTranscript(transcriptData.fullTranscript);\n\n console.log(\"Human readable transcript generated.\");\n\n const payload = {\n videoId,\n title: transcriptData?.title || \"No title found\",\n fullTranscript: transcriptData?.fullTranscript,\n transcriptWithTimeCodes: transcriptData?.transcriptWithTimeCodes,\n readableTranscript: readableTranscript,\n };\n\n console.log(\"Payload:\", payload);\n\n console.log(\"Saving new transcript to database.\");\n\n const transcript = await strapi\n .plugin('yt-transcript-strapi-plugin')\n .service('service')\n .saveTranscript(payload);\n\n ctx.body = { data: transcript };\n },\n});\n\nexport default controller;\n","import controller from './controller';\n\nexport default {\n controller,\n};\n","export default {};\n","export default {};\n","export default [\n {\n method: 'GET',\n path: '/yt-transcript/:videoId',\n handler: 'controller.getTranscript',\n config: { \n policies: [], \n }, \n },\n];","export default [\n {\n method: 'GET',\n path: '/yt-transcript/:videoId',\n handler: 'controller.getTranscript',\n config: { \n policies: [], \n }, \n },\n];","\"use strict\";\n\nimport contentApi from \"./content-api\";\nimport admin from \"./admin\";\n\nexport default {\n \"content-api\": {\n type: \"content-api\",\n routes: [...contentApi],\n },\n admin: {\n type: \"admin\",\n routes: [...admin],\n },\n};","import { ChatOpenAI } from \"@langchain/openai\";\n\ninterface InitializeModelProps {\n openAIApiKey: string;\n model: string;\n temp: number;\n maxTokens?: number;\n}\n\nexport async function initializeModel({\n openAIApiKey,\n model,\n temp,\n}: InitializeModelProps) {\n return new ChatOpenAI({\n temperature: temp,\n openAIApiKey: openAIApiKey,\n modelName: model,\n maxTokens: 1000,\n });\n}","export interface TranscriptSegment {\n text: string;\n start: number;\n end: number;\n duration: number;\n}\n\nexport interface TranscriptData {\n videoId: string;\n fullTranscript: string;\n transcriptWithTimeCodes: TranscriptSegment[];\n}\n\nconst fetchTranscript = async (videoId: string): Promise<TranscriptData> => {\n console.log('Fetching Transcript - Calling fetchTranscript Utils');\n const { Innertube } = await import('youtubei.js');\n\n console.log('Creating YouTube instance');\n\n const youtube = await Innertube.create({\n lang: 'en',\n location: 'US',\n retrieve_player: false,\n });\n\n try {\n const info = await youtube.getInfo(videoId);\n const transcriptData = await info.getTranscript();\n\n console.log('Transcript data fetched');\n\n const transcriptWithTimeCodes: TranscriptSegment[] =\n transcriptData?.transcript?.content?.body?.initial_segments.map((segment) => {\n const segmentDuration = Number(segment.end_ms) - Number(segment.start_ms);\n return {\n text: segment.snippet.text,\n start: Number(segment.start_ms),\n end: Number(segment.end_ms),\n duration: segmentDuration,\n };\n });\n\n console.log('Transcript with time codes generated');\n\n\n const fullTranscript = transcriptData?.transcript?.content?.body?.initial_segments\n .map((segment) => segment.snippet.text)\n .join(' ');\n\n console.log(fullTranscript, 'full transcript');\n console.log('Full transcript generated');\n console.log('Returning transcript data');\n\n return {\n videoId,\n fullTranscript,\n transcriptWithTimeCodes,\n };\n } catch (error) {\n console.error('Error fetching transcript:', error);\n throw error;\n }\n};\n\nexport default fetchTranscript;\n","import type { Core } from '@strapi/strapi';\nimport { ChatOpenAI } from \"@langchain/openai\";\nimport { TokenTextSplitter } from \"@langchain/textsplitters\";\nimport { PromptTemplate } from \"@langchain/core/prompts\";\n\nimport { initializeModel } from \"../utils/openai\";\nimport fetchTranscript from '../utils/fetch-transcript';\n\ninterface YTTranscriptConfig {\n openAIApiKey: string;\n model?: string;\n temp?: number;\n maxTokens?: number;\n}\n\nasync function processTextChunks(chunks: string[], model: ChatOpenAI) {\n const punctuationPrompt = PromptTemplate.fromTemplate(\n \"Add proper punctuation and capitalization to the following text chunk:\\n\\n{chunk}\"\n );\n const punctuationChain = punctuationPrompt.pipe(model);\n\n const processedChunks = await Promise.all(\n chunks.map(async (chunk) => {\n const result = await punctuationChain.invoke({ chunk });\n return result.content as string;\n })\n );\n\n return processedChunks.join(\" \");\n}\n\nexport async function generateModifiedTranscript (rawTranscript: string) {\n const pluginSettings = await strapi.config.get('plugin::yt-transcript-strapi-plugin') as YTTranscriptConfig; \n \n if (!pluginSettings.openAIApiKey || !pluginSettings.model || !pluginSettings.temp || !pluginSettings.maxTokens) {\n throw new Error('Missing required configuration for YTTranscript');\n }\n\n const chatModel = await initializeModel({\n openAIApiKey: pluginSettings.openAIApiKey,\n model: pluginSettings.model,\n temp: pluginSettings.temp,\n maxTokens: pluginSettings.maxTokens,\n });\n\n const splitter = new TokenTextSplitter({\n chunkSize: 1000,\n chunkOverlap: 200,\n });\n\n const transcriptChunks = await splitter.createDocuments([rawTranscript]);\n const chunkTexts = transcriptChunks.map(chunk => chunk.pageContent);\n const modifiedTranscript = await processTextChunks(chunkTexts, chatModel);\n return modifiedTranscript;\n}\n\nconst service = ({ strapi }: { strapi: Core.Strapi }) => ({\n async getTranscript(identifier: string) {\n console.log(\"Fetching Transcript - Calling fetchTranscript Service\");\n const youtubeIdRegex = /^[a-zA-Z0-9_-]{11}$/;\n const isValid = youtubeIdRegex.test(identifier);\n if (!isValid) return { error: 'Invalid video ID', data: null };\n const transcriptData = await fetchTranscript(identifier);\n return transcriptData;\n },\n\n async saveTranscript(payload) {\n // console.log('Saving transcript:', payload);\n return await strapi.documents('plugin::yt-transcript-strapi-plugin.transcript').create({\n data: payload,\n });\n },\n\n async findTranscript(videoId) {\n console.log('Finding transcript for videoId:', videoId);\n const transcriptData = await strapi.documents('plugin::yt-transcript-strapi-plugin.transcript').findFirst({\n filters: { videoId },\n });\n\n\n console.log('Transcript found:', transcriptData?.title, 'found');\n\n if (!transcriptData) return null;\n return transcriptData;\n },\n\n async generateHumanReadableTranscript(transcript) {\n console.log('Generating human readable transcript:');\n const modifiedTranscript = await generateModifiedTranscript(transcript);\n return modifiedTranscript;\n },\n});\n\nexport default service;\n","import service from './service';\n\nexport default {\n service,\n};\n","/**\n * Application methods\n */\nimport bootstrap from './bootstrap';\nimport destroy from './destroy';\nimport register from './register';\n\n/**\n * Plugin server methods\n */\nimport config from './config';\nimport contentTypes from './content-types';\nimport controllers from './controllers';\nimport middlewares from './middlewares';\nimport policies from './policies';\nimport routes from './routes';\nimport services from './services';\n\nexport default {\n register,\n bootstrap,\n destroy,\n config,\n controllers,\n routes,\n services,\n contentTypes,\n policies,\n middlewares,\n};\n"],"names":["strapi","transcript","ChatOpenAI","info","PromptTemplate","TokenTextSplitter"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,MAAM,YAAY,CAAC,EAAE,QAAAA,cAAsC;AAE3D;ACFA,MAAM,UAAU,CAAC,EAAE,QAAAA,cAAsC;AAEzD;ACFA,MAAM,WAAW,CAAC,EAAE,QAAAA,cAAsC;AAE1D;ACJA,MAAe,SAAA;AAAA,EACb,SAAS,CAAC;AAAA,EACV,YAAY;AAAA,EAAA;AACd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACDA,MAAe,aAAA;AAAA,EACb;AACF;ACFA,MAAe,eAAA;AAAA,EACb;AACF;ACJO,SAAS,iBAAiB,SAAgC;AAE/D,QAAM,WAAW;AAGb,MAAA,SAAS,KAAK,OAAO,GAAG;AACnB,WAAA;AAAA,EAAA;AAIT,QAAM,iBAAiB;AAGvB,QAAM,eAAe;AAGf,QAAA,gBAAgB,QAAQ,MAAM,cAAc;AAClD,MAAI,eAAe;AACjB,WAAO,cAAc,CAAC;AAAA,EAAA;AAIlB,QAAA,cAAc,QAAQ,MAAM,YAAY;AAC9C,MAAI,aAAa;AACf,WAAO,YAAY,CAAC;AAAA,EAAA;AAIf,SAAA;AACT;AC3BA,MAAM,aAAa,CAAC,EAAE,QAAAA,eAAuC;AAAA,EAC3D,MAAM,cAAc,KAAK;AACvB,UAAM,UAAU,iBAAiB,IAAI,OAAO,OAAO;AAE/C,QAAA,CAAC,QAAiB,QAAA,IAAI,OAAO,EAAE,OAAO,6BAA6B,MAAM,KAAK;AAElF,YAAQ,IAAI,oCAAoC;AAE1C,UAAA,QAAQ,MAAMA,QACjB,OAAO,6BAA6B,EACpC,QAAQ,SAAS,EACjB,eAAe,OAAO;AAEzB,QAAI,OAAO;AACT,cAAQ,IAAI,mBAAmB;AAC/B,aAAQ,IAAI,OAAO,EAAE,MAAM,MAAM;AAAA,IAAA;AAGnC,YAAQ,IAAI,gDAAgD;AAEtD,UAAA,iBAAiB,MAAMA,QAC1B,OAAO,6BAA6B,EACpC,QAAQ,SAAS,EACjB,cAAc,OAAO;AAExB,YAAQ,IAAI,yBAAyB;AAE/B,UAAA,qBAAqB,MAAMA,QAC9B,OAAO,6BAA6B,EACpC,QAAQ,SAAS,EACjB,gCAAgC,eAAe,cAAc;AAEhE,YAAQ,IAAI,sCAAsC;AAElD,UAAM,UAAU;AAAA,MACd;AAAA,MACA,OAAO,gBAAgB,SAAS;AAAA,MAChC,gBAAgB,gBAAgB;AAAA,MAChC,yBAAyB,gBAAgB;AAAA,MACzC;AAAA,IACF;AAEQ,YAAA,IAAI,YAAY,OAAO;AAE/B,YAAQ,IAAI,oCAAoC;AAE1C,UAAAC,cAAa,MAAMD,QACtB,OAAO,6BAA6B,EACpC,QAAQ,SAAS,EACjB,eAAe,OAAO;AAErB,QAAA,OAAO,EAAE,MAAMC,YAAW;AAAA,EAAA;AAElC;ACrDA,MAAe,cAAA;AAAA,EACb;AACF;ACJA,MAAA,cAAe,CAAC;ACAhB,MAAA,WAAe,CAAC;ACAhB,MAAe,aAAA;AAAA,EACb;AAAA,IACE,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ;AAAA,MACN,UAAU,CAAA;AAAA,IAAC;AAAA,EACb;AAEJ;ACTA,MAAe,QAAA;AAAA,EACb;AAAA,IACE,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ;AAAA,MACN,UAAU,CAAA;AAAA,IAAC;AAAA,EACb;AAEJ;ACJA,MAAe,SAAA;AAAA,EACb,eAAe;AAAA,IACb,MAAM;AAAA,IACN,QAAQ,CAAC,GAAG,UAAU;AAAA,EACxB;AAAA,EACA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,CAAC,GAAG,KAAK;AAAA,EAAA;AAErB;ACLA,eAAsB,gBAAgB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AACF,GAAyB;AACvB,SAAO,IAAIC,OAAAA,WAAW;AAAA,IACpB,aAAa;AAAA,IACb;AAAA,IACA,WAAW;AAAA,IACX,WAAW;AAAA,EAAA,CACZ;AACH;ACPA,MAAM,kBAAkB,OAAO,YAA6C;AAC1E,UAAQ,IAAI,qDAAqD;AACjE,QAAM,EAAE,UAAA,IAAc,MAAM,OAAO,aAAa;AAEhD,UAAQ,IAAI,2BAA2B;AAEjC,QAAA,UAAU,MAAM,UAAU,OAAO;AAAA,IACrC,MAAM;AAAA,IACN,UAAU;AAAA,IACV,iBAAiB;AAAA,EAAA,CAClB;AAEG,MAAA;AACF,UAAMC,QAAO,MAAM,QAAQ,QAAQ,OAAO;AACpC,UAAA,iBAAiB,MAAMA,MAAK,cAAc;AAEhD,YAAQ,IAAI,yBAAyB;AAE/B,UAAA,0BACJ,gBAAgB,YAAY,SAAS,MAAM,iBAAiB,IAAI,CAAC,YAAY;AAC3E,YAAM,kBAAkB,OAAO,QAAQ,MAAM,IAAI,OAAO,QAAQ,QAAQ;AACjE,aAAA;AAAA,QACL,MAAM,QAAQ,QAAQ;AAAA,QACtB,OAAO,OAAO,QAAQ,QAAQ;AAAA,QAC9B,KAAK,OAAO,QAAQ,MAAM;AAAA,QAC1B,UAAU;AAAA,MACZ;AAAA,IAAA,CACD;AAEH,YAAQ,IAAI,sCAAsC;AAGlD,UAAM,iBAAiB,gBAAgB,YAAY,SAAS,MAAM,iBAC/D,IAAI,CAAC,YAAY,QAAQ,QAAQ,IAAI,EACrC,KAAK,GAAG;AAEH,YAAA,IAAI,gBAAgB,iBAAiB;AAC7C,YAAQ,IAAI,2BAA2B;AACvC,YAAQ,IAAI,2BAA2B;AAEhC,WAAA;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,WACO,OAAO;AACN,YAAA,MAAM,8BAA8B,KAAK;AAC3C,UAAA;AAAA,EAAA;AAEV;AC/CA,eAAe,kBAAkB,QAAkB,OAAmB;AACpE,QAAM,oBAAoBC,QAAAA,eAAe;AAAA,IACvC;AAAA,EACF;AACM,QAAA,mBAAmB,kBAAkB,KAAK,KAAK;AAE/C,QAAA,kBAAkB,MAAM,QAAQ;AAAA,IACpC,OAAO,IAAI,OAAO,UAAU;AAC1B,YAAM,SAAS,MAAM,iBAAiB,OAAO,EAAE,OAAO;AACtD,aAAO,OAAO;AAAA,IACf,CAAA;AAAA,EACH;AAEO,SAAA,gBAAgB,KAAK,GAAG;AACjC;AAEA,eAAsB,2BAA4B,eAAuB;AACvE,QAAM,iBAAiB,MAAM,OAAO,OAAO,IAAI,qCAAqC;AAEhF,MAAA,CAAC,eAAe,gBAAgB,CAAC,eAAe,SAAS,CAAC,eAAe,QAAQ,CAAC,eAAe,WAAW;AACxG,UAAA,IAAI,MAAM,iDAAiD;AAAA,EAAA;AAG7D,QAAA,YAAY,MAAM,gBAAgB;AAAA,IACtC,cAAc,eAAe;AAAA,IAC7B,OAAO,eAAe;AAAA,IACtB,MAAM,eAAe;AAAA,IACrB,WAAW,eAAe;AAAA,EAAA,CAC3B;AAEK,QAAA,WAAW,IAAIC,gCAAkB;AAAA,IACrC,WAAW;AAAA,IACX,cAAc;AAAA,EAAA,CACf;AAED,QAAM,mBAAmB,MAAM,SAAS,gBAAgB,CAAC,aAAa,CAAC;AACvE,QAAM,aAAa,iBAAiB,IAAI,CAAA,UAAS,MAAM,WAAW;AAClE,QAAM,qBAAqB,MAAM,kBAAkB,YAAY,SAAS;AACjE,SAAA;AACT;AAEA,MAAM,UAAU,CAAC,EAAE,QAAAL,eAAuC;AAAA,EACxD,MAAM,cAAc,YAAoB;AACtC,YAAQ,IAAI,uDAAuD;AACnE,UAAM,iBAAiB;AACjB,UAAA,UAAU,eAAe,KAAK,UAAU;AAC9C,QAAI,CAAC,QAAS,QAAO,EAAE,OAAO,oBAAoB,MAAM,KAAK;AACvD,UAAA,iBAAiB,MAAM,gBAAgB,UAAU;AAChD,WAAA;AAAA,EACT;AAAA,EAEA,MAAM,eAAe,SAAS;AAE5B,WAAO,MAAMA,QAAO,UAAU,gDAAgD,EAAE,OAAO;AAAA,MACrF,MAAM;AAAA,IAAA,CACP;AAAA,EACH;AAAA,EAEA,MAAM,eAAe,SAAS;AACpB,YAAA,IAAI,mCAAmC,OAAO;AACtD,UAAM,iBAAmB,MAAMA,QAAO,UAAU,gDAAgD,EAAE,UAAU;AAAA,MAC1G,SAAS,EAAE,QAAQ;AAAA,IAAA,CACpB;AAGD,YAAQ,IAAI,qBAAqB,gBAAgB,OAAO,OAAO;AAE3D,QAAA,CAAC,eAAuB,QAAA;AACrB,WAAA;AAAA,EACT;AAAA,EAEA,MAAM,gCAAgCC,aAAY;AAChD,YAAQ,IAAI,uCAAuC;AAC7C,UAAA,qBAAqB,MAAM,2BAA2BA,WAAU;AAC/D,WAAA;AAAA,EAAA;AAEX;ACzFA,MAAe,WAAA;AAAA,EACb;AACF;ACcA,MAAe,QAAA;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;"}
@@ -1,273 +0,0 @@
1
- import { TokenTextSplitter } from "@langchain/textsplitters";
2
- import { PromptTemplate } from "@langchain/core/prompts";
3
- import { ChatOpenAI } from "@langchain/openai";
4
- const bootstrap = ({ strapi: strapi2 }) => {
5
- };
6
- const destroy = ({ strapi: strapi2 }) => {
7
- };
8
- const register = ({ strapi: strapi2 }) => {
9
- };
10
- const config = {
11
- default: {},
12
- validator() {
13
- }
14
- };
15
- const kind = "collectionType";
16
- const collectionName = "transcript";
17
- const info = {
18
- singularName: "transcript",
19
- pluralName: "transcripts",
20
- displayName: "Transcript"
21
- };
22
- const options = {
23
- draftAndPublish: false
24
- };
25
- const pluginOptions = {
26
- "content-manager": {
27
- visible: true
28
- },
29
- "content-type-builder": {
30
- visible: true
31
- }
32
- };
33
- const attributes = {
34
- title: {
35
- type: "string"
36
- },
37
- videoId: {
38
- type: "string"
39
- },
40
- fullTranscript: {
41
- type: "richtext"
42
- },
43
- transcriptWithTimeCodes: {
44
- type: "json"
45
- },
46
- readableTranscript: {
47
- type: "richtext"
48
- }
49
- };
50
- const schema = {
51
- kind,
52
- collectionName,
53
- info,
54
- options,
55
- pluginOptions,
56
- attributes
57
- };
58
- const transcript = {
59
- schema
60
- };
61
- const contentTypes = {
62
- transcript
63
- };
64
- function extractYouTubeID(urlOrID) {
65
- const regExpID = /^[a-zA-Z0-9_-]{11}$/;
66
- if (regExpID.test(urlOrID)) {
67
- return urlOrID;
68
- }
69
- const regExpStandard = /youtube\.com\/watch\?v=([a-zA-Z0-9_-]+)/;
70
- const regExpShorts = /youtube\.com\/shorts\/([a-zA-Z0-9_-]+)/;
71
- const matchStandard = urlOrID.match(regExpStandard);
72
- if (matchStandard) {
73
- return matchStandard[1];
74
- }
75
- const matchShorts = urlOrID.match(regExpShorts);
76
- if (matchShorts) {
77
- return matchShorts[1];
78
- }
79
- return null;
80
- }
81
- const controller = ({ strapi: strapi2 }) => ({
82
- async getTranscript(ctx) {
83
- const videoId = extractYouTubeID(ctx.params.videoId);
84
- if (!videoId) return ctx.body = { error: "Invalid YouTube URL or ID", data: null };
85
- console.log("Looking for transcript in database");
86
- const found = await strapi2.plugin("yt-transcript-strapi-plugin").service("service").findTranscript(videoId);
87
- if (found) {
88
- console.log("Transcript found.");
89
- return ctx.body = { data: found };
90
- }
91
- console.log("Transcript not found. Fetching new transcript.");
92
- const transcriptData = await strapi2.plugin("yt-transcript-strapi-plugin").service("service").getTranscript(videoId);
93
- console.log("New transcript fetched.");
94
- const readableTranscript = await strapi2.plugin("yt-transcript-strapi-plugin").service("service").generateHumanReadableTranscript(transcriptData.fullTranscript);
95
- console.log("Human readable transcript generated.");
96
- const payload = {
97
- videoId,
98
- title: transcriptData?.title || "No title found",
99
- fullTranscript: transcriptData?.fullTranscript,
100
- transcriptWithTimeCodes: transcriptData?.transcriptWithTimeCodes,
101
- readableTranscript
102
- };
103
- console.log("Payload:", payload);
104
- console.log("Saving new transcript to database.");
105
- const transcript2 = await strapi2.plugin("yt-transcript-strapi-plugin").service("service").saveTranscript(payload);
106
- ctx.body = { data: transcript2 };
107
- }
108
- });
109
- const controllers = {
110
- controller
111
- };
112
- const middlewares = {};
113
- const policies = {};
114
- const contentApi = [
115
- {
116
- method: "GET",
117
- path: "/yt-transcript/:videoId",
118
- handler: "controller.getTranscript",
119
- config: {
120
- policies: []
121
- }
122
- }
123
- ];
124
- const admin = [
125
- {
126
- method: "GET",
127
- path: "/yt-transcript/:videoId",
128
- handler: "controller.getTranscript",
129
- config: {
130
- policies: []
131
- }
132
- }
133
- ];
134
- const routes = {
135
- "content-api": {
136
- type: "content-api",
137
- routes: [...contentApi]
138
- },
139
- admin: {
140
- type: "admin",
141
- routes: [...admin]
142
- }
143
- };
144
- async function initializeModel({
145
- openAIApiKey,
146
- model,
147
- temp
148
- }) {
149
- return new ChatOpenAI({
150
- temperature: temp,
151
- openAIApiKey,
152
- modelName: model,
153
- maxTokens: 1e3
154
- });
155
- }
156
- const fetchTranscript = async (videoId) => {
157
- console.log("Fetching Transcript - Calling fetchTranscript Utils");
158
- const { Innertube } = await import("youtubei.js");
159
- console.log("Creating YouTube instance");
160
- const youtube = await Innertube.create({
161
- lang: "en",
162
- location: "US",
163
- retrieve_player: false
164
- });
165
- try {
166
- const info2 = await youtube.getInfo(videoId);
167
- const transcriptData = await info2.getTranscript();
168
- console.log("Transcript data fetched");
169
- const transcriptWithTimeCodes = transcriptData?.transcript?.content?.body?.initial_segments.map((segment) => {
170
- const segmentDuration = Number(segment.end_ms) - Number(segment.start_ms);
171
- return {
172
- text: segment.snippet.text,
173
- start: Number(segment.start_ms),
174
- end: Number(segment.end_ms),
175
- duration: segmentDuration
176
- };
177
- });
178
- console.log("Transcript with time codes generated");
179
- const fullTranscript = transcriptData?.transcript?.content?.body?.initial_segments.map((segment) => segment.snippet.text).join(" ");
180
- console.log(fullTranscript, "full transcript");
181
- console.log("Full transcript generated");
182
- console.log("Returning transcript data");
183
- return {
184
- videoId,
185
- fullTranscript,
186
- transcriptWithTimeCodes
187
- };
188
- } catch (error) {
189
- console.error("Error fetching transcript:", error);
190
- throw error;
191
- }
192
- };
193
- async function processTextChunks(chunks, model) {
194
- const punctuationPrompt = PromptTemplate.fromTemplate(
195
- "Add proper punctuation and capitalization to the following text chunk:\n\n{chunk}"
196
- );
197
- const punctuationChain = punctuationPrompt.pipe(model);
198
- const processedChunks = await Promise.all(
199
- chunks.map(async (chunk) => {
200
- const result = await punctuationChain.invoke({ chunk });
201
- return result.content;
202
- })
203
- );
204
- return processedChunks.join(" ");
205
- }
206
- async function generateModifiedTranscript(rawTranscript) {
207
- const pluginSettings = await strapi.config.get("plugin::yt-transcript-strapi-plugin");
208
- if (!pluginSettings.openAIApiKey || !pluginSettings.model || !pluginSettings.temp || !pluginSettings.maxTokens) {
209
- throw new Error("Missing required configuration for YTTranscript");
210
- }
211
- const chatModel = await initializeModel({
212
- openAIApiKey: pluginSettings.openAIApiKey,
213
- model: pluginSettings.model,
214
- temp: pluginSettings.temp,
215
- maxTokens: pluginSettings.maxTokens
216
- });
217
- const splitter = new TokenTextSplitter({
218
- chunkSize: 1e3,
219
- chunkOverlap: 200
220
- });
221
- const transcriptChunks = await splitter.createDocuments([rawTranscript]);
222
- const chunkTexts = transcriptChunks.map((chunk) => chunk.pageContent);
223
- const modifiedTranscript = await processTextChunks(chunkTexts, chatModel);
224
- return modifiedTranscript;
225
- }
226
- const service = ({ strapi: strapi2 }) => ({
227
- async getTranscript(identifier) {
228
- console.log("Fetching Transcript - Calling fetchTranscript Service");
229
- const youtubeIdRegex = /^[a-zA-Z0-9_-]{11}$/;
230
- const isValid = youtubeIdRegex.test(identifier);
231
- if (!isValid) return { error: "Invalid video ID", data: null };
232
- const transcriptData = await fetchTranscript(identifier);
233
- return transcriptData;
234
- },
235
- async saveTranscript(payload) {
236
- return await strapi2.documents("plugin::yt-transcript-strapi-plugin.transcript").create({
237
- data: payload
238
- });
239
- },
240
- async findTranscript(videoId) {
241
- console.log("Finding transcript for videoId:", videoId);
242
- const transcriptData = await strapi2.documents("plugin::yt-transcript-strapi-plugin.transcript").findFirst({
243
- filters: { videoId }
244
- });
245
- console.log("Transcript found:", transcriptData?.title, "found");
246
- if (!transcriptData) return null;
247
- return transcriptData;
248
- },
249
- async generateHumanReadableTranscript(transcript2) {
250
- console.log("Generating human readable transcript:");
251
- const modifiedTranscript = await generateModifiedTranscript(transcript2);
252
- return modifiedTranscript;
253
- }
254
- });
255
- const services = {
256
- service
257
- };
258
- const index = {
259
- register,
260
- bootstrap,
261
- destroy,
262
- config,
263
- controllers,
264
- routes,
265
- services,
266
- contentTypes,
267
- policies,
268
- middlewares
269
- };
270
- export {
271
- index as default
272
- };
273
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs","sources":["../../server/src/bootstrap.ts","../../server/src/destroy.ts","../../server/src/register.ts","../../server/src/config/index.ts","../../server/src/content-types/transcript/index.ts","../../server/src/content-types/index.ts","../../server/src/utils/extract-youtube-id.ts","../../server/src/controllers/controller.ts","../../server/src/controllers/index.ts","../../server/src/middlewares/index.ts","../../server/src/policies/index.ts","../../server/src/routes/content-api.ts","../../server/src/routes/admin.ts","../../server/src/routes/index.ts","../../server/src/utils/openai.ts","../../server/src/utils/fetch-transcript.ts","../../server/src/services/service.ts","../../server/src/services/index.ts","../../server/src/index.ts"],"sourcesContent":["import type { Core } from '@strapi/strapi';\n\nconst bootstrap = ({ strapi }: { strapi: Core.Strapi }) => {\n // bootstrap phase\n};\n\nexport default bootstrap;\n","import type { Core } from '@strapi/strapi';\n\nconst destroy = ({ strapi }: { strapi: Core.Strapi }) => {\n // destroy phase\n};\n\nexport default destroy;\n","import type { Core } from '@strapi/strapi';\n\nconst register = ({ strapi }: { strapi: Core.Strapi }) => {\n // register phase\n};\n\nexport default register;\n","export default {\n default: {},\n validator() {},\n};\n","import schema from './schema.json';\n\nexport default {\n schema,\n};","import transcript from './transcript';\n\nexport default {\n transcript,\n};\n\n\n","export function extractYouTubeID(urlOrID: string): string | null {\n // Regular expression for YouTube ID format\n const regExpID = /^[a-zA-Z0-9_-]{11}$/;\n\n // Check if the input is a YouTube ID\n if (regExpID.test(urlOrID)) {\n return urlOrID;\n }\n\n // Regular expression for standard YouTube links\n const regExpStandard = /youtube\\.com\\/watch\\?v=([a-zA-Z0-9_-]+)/;\n\n // Regular expression for YouTube Shorts links\n const regExpShorts = /youtube\\.com\\/shorts\\/([a-zA-Z0-9_-]+)/;\n\n // Check for standard YouTube link\n const matchStandard = urlOrID.match(regExpStandard);\n if (matchStandard) {\n return matchStandard[1];\n }\n\n // Check for YouTube Shorts link\n const matchShorts = urlOrID.match(regExpShorts);\n if (matchShorts) {\n return matchShorts[1];\n }\n\n // Return null if no match is found\n return null;\n}","import type { Core } from '@strapi/strapi';\nimport { extractYouTubeID } from '../utils/extract-youtube-id';\nconst controller = ({ strapi }: { strapi: Core.Strapi }) => ({\n async getTranscript(ctx) {\n const videoId = extractYouTubeID(ctx.params.videoId);\n\n if (!videoId) return (ctx.body = { error: 'Invalid YouTube URL or ID', data: null });\n\n console.log(\"Looking for transcript in database\");\n\n const found = await strapi\n .plugin('yt-transcript-strapi-plugin')\n .service('service')\n .findTranscript(videoId);\n\n if (found) {\n console.log(\"Transcript found.\");\n return (ctx.body = { data: found });\n }\n\n console.log(\"Transcript not found. Fetching new transcript.\");\n\n const transcriptData = await strapi\n .plugin('yt-transcript-strapi-plugin')\n .service('service')\n .getTranscript(videoId);\n\n console.log(\"New transcript fetched.\");\n\n const readableTranscript = await strapi\n .plugin('yt-transcript-strapi-plugin')\n .service('service')\n .generateHumanReadableTranscript(transcriptData.fullTranscript);\n\n console.log(\"Human readable transcript generated.\");\n\n const payload = {\n videoId,\n title: transcriptData?.title || \"No title found\",\n fullTranscript: transcriptData?.fullTranscript,\n transcriptWithTimeCodes: transcriptData?.transcriptWithTimeCodes,\n readableTranscript: readableTranscript,\n };\n\n console.log(\"Payload:\", payload);\n\n console.log(\"Saving new transcript to database.\");\n\n const transcript = await strapi\n .plugin('yt-transcript-strapi-plugin')\n .service('service')\n .saveTranscript(payload);\n\n ctx.body = { data: transcript };\n },\n});\n\nexport default controller;\n","import controller from './controller';\n\nexport default {\n controller,\n};\n","export default {};\n","export default {};\n","export default [\n {\n method: 'GET',\n path: '/yt-transcript/:videoId',\n handler: 'controller.getTranscript',\n config: { \n policies: [], \n }, \n },\n];","export default [\n {\n method: 'GET',\n path: '/yt-transcript/:videoId',\n handler: 'controller.getTranscript',\n config: { \n policies: [], \n }, \n },\n];","\"use strict\";\n\nimport contentApi from \"./content-api\";\nimport admin from \"./admin\";\n\nexport default {\n \"content-api\": {\n type: \"content-api\",\n routes: [...contentApi],\n },\n admin: {\n type: \"admin\",\n routes: [...admin],\n },\n};","import { ChatOpenAI } from \"@langchain/openai\";\n\ninterface InitializeModelProps {\n openAIApiKey: string;\n model: string;\n temp: number;\n maxTokens?: number;\n}\n\nexport async function initializeModel({\n openAIApiKey,\n model,\n temp,\n}: InitializeModelProps) {\n return new ChatOpenAI({\n temperature: temp,\n openAIApiKey: openAIApiKey,\n modelName: model,\n maxTokens: 1000,\n });\n}","export interface TranscriptSegment {\n text: string;\n start: number;\n end: number;\n duration: number;\n}\n\nexport interface TranscriptData {\n videoId: string;\n fullTranscript: string;\n transcriptWithTimeCodes: TranscriptSegment[];\n}\n\nconst fetchTranscript = async (videoId: string): Promise<TranscriptData> => {\n console.log('Fetching Transcript - Calling fetchTranscript Utils');\n const { Innertube } = await import('youtubei.js');\n\n console.log('Creating YouTube instance');\n\n const youtube = await Innertube.create({\n lang: 'en',\n location: 'US',\n retrieve_player: false,\n });\n\n try {\n const info = await youtube.getInfo(videoId);\n const transcriptData = await info.getTranscript();\n\n console.log('Transcript data fetched');\n\n const transcriptWithTimeCodes: TranscriptSegment[] =\n transcriptData?.transcript?.content?.body?.initial_segments.map((segment) => {\n const segmentDuration = Number(segment.end_ms) - Number(segment.start_ms);\n return {\n text: segment.snippet.text,\n start: Number(segment.start_ms),\n end: Number(segment.end_ms),\n duration: segmentDuration,\n };\n });\n\n console.log('Transcript with time codes generated');\n\n\n const fullTranscript = transcriptData?.transcript?.content?.body?.initial_segments\n .map((segment) => segment.snippet.text)\n .join(' ');\n\n console.log(fullTranscript, 'full transcript');\n console.log('Full transcript generated');\n console.log('Returning transcript data');\n\n return {\n videoId,\n fullTranscript,\n transcriptWithTimeCodes,\n };\n } catch (error) {\n console.error('Error fetching transcript:', error);\n throw error;\n }\n};\n\nexport default fetchTranscript;\n","import type { Core } from '@strapi/strapi';\nimport { ChatOpenAI } from \"@langchain/openai\";\nimport { TokenTextSplitter } from \"@langchain/textsplitters\";\nimport { PromptTemplate } from \"@langchain/core/prompts\";\n\nimport { initializeModel } from \"../utils/openai\";\nimport fetchTranscript from '../utils/fetch-transcript';\n\ninterface YTTranscriptConfig {\n openAIApiKey: string;\n model?: string;\n temp?: number;\n maxTokens?: number;\n}\n\nasync function processTextChunks(chunks: string[], model: ChatOpenAI) {\n const punctuationPrompt = PromptTemplate.fromTemplate(\n \"Add proper punctuation and capitalization to the following text chunk:\\n\\n{chunk}\"\n );\n const punctuationChain = punctuationPrompt.pipe(model);\n\n const processedChunks = await Promise.all(\n chunks.map(async (chunk) => {\n const result = await punctuationChain.invoke({ chunk });\n return result.content as string;\n })\n );\n\n return processedChunks.join(\" \");\n}\n\nexport async function generateModifiedTranscript (rawTranscript: string) {\n const pluginSettings = await strapi.config.get('plugin::yt-transcript-strapi-plugin') as YTTranscriptConfig; \n \n if (!pluginSettings.openAIApiKey || !pluginSettings.model || !pluginSettings.temp || !pluginSettings.maxTokens) {\n throw new Error('Missing required configuration for YTTranscript');\n }\n\n const chatModel = await initializeModel({\n openAIApiKey: pluginSettings.openAIApiKey,\n model: pluginSettings.model,\n temp: pluginSettings.temp,\n maxTokens: pluginSettings.maxTokens,\n });\n\n const splitter = new TokenTextSplitter({\n chunkSize: 1000,\n chunkOverlap: 200,\n });\n\n const transcriptChunks = await splitter.createDocuments([rawTranscript]);\n const chunkTexts = transcriptChunks.map(chunk => chunk.pageContent);\n const modifiedTranscript = await processTextChunks(chunkTexts, chatModel);\n return modifiedTranscript;\n}\n\nconst service = ({ strapi }: { strapi: Core.Strapi }) => ({\n async getTranscript(identifier: string) {\n console.log(\"Fetching Transcript - Calling fetchTranscript Service\");\n const youtubeIdRegex = /^[a-zA-Z0-9_-]{11}$/;\n const isValid = youtubeIdRegex.test(identifier);\n if (!isValid) return { error: 'Invalid video ID', data: null };\n const transcriptData = await fetchTranscript(identifier);\n return transcriptData;\n },\n\n async saveTranscript(payload) {\n // console.log('Saving transcript:', payload);\n return await strapi.documents('plugin::yt-transcript-strapi-plugin.transcript').create({\n data: payload,\n });\n },\n\n async findTranscript(videoId) {\n console.log('Finding transcript for videoId:', videoId);\n const transcriptData = await strapi.documents('plugin::yt-transcript-strapi-plugin.transcript').findFirst({\n filters: { videoId },\n });\n\n\n console.log('Transcript found:', transcriptData?.title, 'found');\n\n if (!transcriptData) return null;\n return transcriptData;\n },\n\n async generateHumanReadableTranscript(transcript) {\n console.log('Generating human readable transcript:');\n const modifiedTranscript = await generateModifiedTranscript(transcript);\n return modifiedTranscript;\n },\n});\n\nexport default service;\n","import service from './service';\n\nexport default {\n service,\n};\n","/**\n * Application methods\n */\nimport bootstrap from './bootstrap';\nimport destroy from './destroy';\nimport register from './register';\n\n/**\n * Plugin server methods\n */\nimport config from './config';\nimport contentTypes from './content-types';\nimport controllers from './controllers';\nimport middlewares from './middlewares';\nimport policies from './policies';\nimport routes from './routes';\nimport services from './services';\n\nexport default {\n register,\n bootstrap,\n destroy,\n config,\n controllers,\n routes,\n services,\n contentTypes,\n policies,\n middlewares,\n};\n"],"names":["strapi","transcript","info"],"mappings":"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"}
@@ -1,5 +0,0 @@
1
- import type { Core } from '@strapi/strapi';
2
- declare const bootstrap: ({ strapi }: {
3
- strapi: Core.Strapi;
4
- }) => void;
5
- export default bootstrap;
@@ -1,5 +0,0 @@
1
- declare const _default: {
2
- default: {};
3
- validator(): void;
4
- };
5
- export default _default;
@@ -1,42 +0,0 @@
1
- declare const _default: {
2
- transcript: {
3
- schema: {
4
- kind: string;
5
- collectionName: string;
6
- info: {
7
- singularName: string;
8
- pluralName: string;
9
- displayName: string;
10
- };
11
- options: {
12
- draftAndPublish: boolean;
13
- };
14
- pluginOptions: {
15
- "content-manager": {
16
- visible: boolean;
17
- };
18
- "content-type-builder": {
19
- visible: boolean;
20
- };
21
- };
22
- attributes: {
23
- title: {
24
- type: string;
25
- };
26
- videoId: {
27
- type: string;
28
- };
29
- fullTranscript: {
30
- type: string;
31
- };
32
- transcriptWithTimeCodes: {
33
- type: string;
34
- };
35
- readableTranscript: {
36
- type: string;
37
- };
38
- };
39
- };
40
- };
41
- };
42
- export default _default;
@@ -1,40 +0,0 @@
1
- declare const _default: {
2
- schema: {
3
- kind: string;
4
- collectionName: string;
5
- info: {
6
- singularName: string;
7
- pluralName: string;
8
- displayName: string;
9
- };
10
- options: {
11
- draftAndPublish: boolean;
12
- };
13
- pluginOptions: {
14
- "content-manager": {
15
- visible: boolean;
16
- };
17
- "content-type-builder": {
18
- visible: boolean;
19
- };
20
- };
21
- attributes: {
22
- title: {
23
- type: string;
24
- };
25
- videoId: {
26
- type: string;
27
- };
28
- fullTranscript: {
29
- type: string;
30
- };
31
- transcriptWithTimeCodes: {
32
- type: string;
33
- };
34
- readableTranscript: {
35
- type: string;
36
- };
37
- };
38
- };
39
- };
40
- export default _default;
@@ -1,13 +0,0 @@
1
- import type { Core } from '@strapi/strapi';
2
- declare const controller: ({ strapi }: {
3
- strapi: Core.Strapi;
4
- }) => {
5
- getTranscript(ctx: any): Promise<{
6
- error: string;
7
- data: any;
8
- } | {
9
- data: any;
10
- error?: undefined;
11
- }>;
12
- };
13
- export default controller;
@@ -1,14 +0,0 @@
1
- declare const _default: {
2
- controller: ({ strapi }: {
3
- strapi: import("@strapi/types/dist/core").Strapi;
4
- }) => {
5
- getTranscript(ctx: any): Promise<{
6
- error: string;
7
- data: any;
8
- } | {
9
- data: any;
10
- error?: undefined;
11
- }>;
12
- };
13
- };
14
- export default _default;
@@ -1,5 +0,0 @@
1
- import type { Core } from '@strapi/strapi';
2
- declare const destroy: ({ strapi }: {
3
- strapi: Core.Strapi;
4
- }) => void;
5
- export default destroy;
@@ -1,109 +0,0 @@
1
- declare const _default: {
2
- register: ({ strapi }: {
3
- strapi: import("@strapi/types/dist/core").Strapi;
4
- }) => void;
5
- bootstrap: ({ strapi }: {
6
- strapi: import("@strapi/types/dist/core").Strapi;
7
- }) => void;
8
- destroy: ({ strapi }: {
9
- strapi: import("@strapi/types/dist/core").Strapi;
10
- }) => void;
11
- config: {
12
- default: {};
13
- validator(): void;
14
- };
15
- controllers: {
16
- controller: ({ strapi }: {
17
- strapi: import("@strapi/types/dist/core").Strapi;
18
- }) => {
19
- getTranscript(ctx: any): Promise<{
20
- error: string;
21
- data: any;
22
- } | {
23
- data: any;
24
- error?: undefined;
25
- }>;
26
- };
27
- };
28
- routes: {
29
- "content-api": {
30
- type: string;
31
- routes: {
32
- method: string;
33
- path: string;
34
- handler: string;
35
- config: {
36
- policies: any[];
37
- };
38
- }[];
39
- };
40
- admin: {
41
- type: string;
42
- routes: {
43
- method: string;
44
- path: string;
45
- handler: string;
46
- config: {
47
- policies: any[];
48
- };
49
- }[];
50
- };
51
- };
52
- services: {
53
- service: ({ strapi }: {
54
- strapi: import("@strapi/types/dist/core").Strapi;
55
- }) => {
56
- getTranscript(identifier: string): Promise<import("./utils/fetch-transcript").TranscriptData | {
57
- error: string;
58
- data: any;
59
- }>;
60
- saveTranscript(payload: any): Promise<import("@strapi/types/dist/modules/documents").AnyDocument>;
61
- findTranscript(videoId: any): Promise<import("@strapi/types/dist/modules/documents").AnyDocument>;
62
- generateHumanReadableTranscript(transcript: any): Promise<string>;
63
- };
64
- };
65
- contentTypes: {
66
- transcript: {
67
- schema: {
68
- kind: string;
69
- collectionName: string;
70
- info: {
71
- singularName: string;
72
- pluralName: string;
73
- displayName: string;
74
- };
75
- options: {
76
- draftAndPublish: boolean;
77
- };
78
- pluginOptions: {
79
- "content-manager": {
80
- visible: boolean;
81
- };
82
- "content-type-builder": {
83
- visible: boolean;
84
- };
85
- };
86
- attributes: {
87
- title: {
88
- type: string;
89
- };
90
- videoId: {
91
- type: string;
92
- };
93
- fullTranscript: {
94
- type: string;
95
- };
96
- transcriptWithTimeCodes: {
97
- type: string;
98
- };
99
- readableTranscript: {
100
- type: string;
101
- };
102
- };
103
- };
104
- };
105
- };
106
- policies: {};
107
- middlewares: {};
108
- };
109
- export default _default;
@@ -1,2 +0,0 @@
1
- declare const _default: {};
2
- export default _default;
@@ -1,2 +0,0 @@
1
- declare const _default: {};
2
- export default _default;
@@ -1,5 +0,0 @@
1
- import type { Core } from '@strapi/strapi';
2
- declare const register: ({ strapi }: {
3
- strapi: Core.Strapi;
4
- }) => void;
5
- export default register;
@@ -1,9 +0,0 @@
1
- declare const _default: {
2
- method: string;
3
- path: string;
4
- handler: string;
5
- config: {
6
- policies: any[];
7
- };
8
- }[];
9
- export default _default;
@@ -1,9 +0,0 @@
1
- declare const _default: {
2
- method: string;
3
- path: string;
4
- handler: string;
5
- config: {
6
- policies: any[];
7
- };
8
- }[];
9
- export default _default;
@@ -1,25 +0,0 @@
1
- declare const _default: {
2
- "content-api": {
3
- type: string;
4
- routes: {
5
- method: string;
6
- path: string;
7
- handler: string;
8
- config: {
9
- policies: any[];
10
- };
11
- }[];
12
- };
13
- admin: {
14
- type: string;
15
- routes: {
16
- method: string;
17
- path: string;
18
- handler: string;
19
- config: {
20
- policies: any[];
21
- };
22
- }[];
23
- };
24
- };
25
- export default _default;
@@ -1,14 +0,0 @@
1
- declare const _default: {
2
- service: ({ strapi }: {
3
- strapi: import("@strapi/types/dist/core").Strapi;
4
- }) => {
5
- getTranscript(identifier: string): Promise<import("../utils/fetch-transcript").TranscriptData | {
6
- error: string;
7
- data: any;
8
- }>;
9
- saveTranscript(payload: any): Promise<import("@strapi/types/dist/modules/documents").AnyDocument>;
10
- findTranscript(videoId: any): Promise<import("@strapi/types/dist/modules/documents").AnyDocument>;
11
- generateHumanReadableTranscript(transcript: any): Promise<string>;
12
- };
13
- };
14
- export default _default;
@@ -1,14 +0,0 @@
1
- import type { Core } from '@strapi/strapi';
2
- export declare function generateModifiedTranscript(rawTranscript: string): Promise<string>;
3
- declare const service: ({ strapi }: {
4
- strapi: Core.Strapi;
5
- }) => {
6
- getTranscript(identifier: string): Promise<import("../utils/fetch-transcript").TranscriptData | {
7
- error: string;
8
- data: any;
9
- }>;
10
- saveTranscript(payload: any): Promise<import("@strapi/types/dist/modules/documents").AnyDocument>;
11
- findTranscript(videoId: any): Promise<import("@strapi/types/dist/modules/documents").AnyDocument>;
12
- generateHumanReadableTranscript(transcript: any): Promise<string>;
13
- };
14
- export default service;
@@ -1 +0,0 @@
1
- export declare function extractYouTubeID(urlOrID: string): string | null;
@@ -1,13 +0,0 @@
1
- export interface TranscriptSegment {
2
- text: string;
3
- start: number;
4
- end: number;
5
- duration: number;
6
- }
7
- export interface TranscriptData {
8
- videoId: string;
9
- fullTranscript: string;
10
- transcriptWithTimeCodes: TranscriptSegment[];
11
- }
12
- declare const fetchTranscript: (videoId: string) => Promise<TranscriptData>;
13
- export default fetchTranscript;
@@ -1,9 +0,0 @@
1
- import { ChatOpenAI } from "@langchain/openai";
2
- interface InitializeModelProps {
3
- openAIApiKey: string;
4
- model: string;
5
- temp: number;
6
- maxTokens?: number;
7
- }
8
- export declare function initializeModel({ openAIApiKey, model, temp, }: InitializeModelProps): Promise<ChatOpenAI<import("@langchain/openai").ChatOpenAICallOptions>>;
9
- export {};