yt-transcript-strapi-plugin 0.0.21 → 0.0.22
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.
- package/dist/server/index.js +44 -124
- package/dist/server/index.mjs +44 -124
- package/dist/server/src/content-types/index.d.ts +0 -3
- package/dist/server/src/content-types/transcript/index.d.ts +0 -3
- package/dist/server/src/index.d.ts +0 -4
- package/dist/server/src/mcp/schemas/index.d.ts +0 -6
- package/dist/server/src/mcp/tools/fetch-transcript.d.ts +0 -5
- package/dist/server/src/mcp/tools/index.d.ts +13 -13
- package/dist/server/src/services/index.d.ts +0 -1
- package/dist/server/src/services/service.d.ts +0 -2
- package/node_modules/express/node_modules/media-typer/HISTORY.md +50 -0
- package/node_modules/express/node_modules/media-typer/LICENSE +22 -0
- package/node_modules/express/node_modules/media-typer/README.md +93 -0
- package/node_modules/express/node_modules/media-typer/index.js +143 -0
- package/node_modules/express/node_modules/media-typer/package.json +33 -0
- package/node_modules/express/node_modules/type-is/HISTORY.md +292 -0
- package/node_modules/express/node_modules/type-is/LICENSE +23 -0
- package/node_modules/express/node_modules/type-is/README.md +198 -0
- package/node_modules/express/node_modules/type-is/index.js +250 -0
- package/node_modules/express/node_modules/type-is/package.json +47 -0
- package/package.json +1 -5
- package/dist/server/src/utils/openai.d.ts +0 -9
- package/node_modules/which/CHANGELOG.md +0 -166
- /package/node_modules/{media-typer → body-parser/node_modules/media-typer}/HISTORY.md +0 -0
- /package/node_modules/{media-typer → body-parser/node_modules/media-typer}/LICENSE +0 -0
- /package/node_modules/{media-typer → body-parser/node_modules/media-typer}/README.md +0 -0
- /package/node_modules/{media-typer → body-parser/node_modules/media-typer}/index.js +0 -0
- /package/node_modules/{media-typer → body-parser/node_modules/media-typer}/package.json +0 -0
- /package/node_modules/{type-is → body-parser}/node_modules/mime-types/HISTORY.md +0 -0
- /package/node_modules/{type-is → body-parser}/node_modules/mime-types/LICENSE +0 -0
- /package/node_modules/{type-is → body-parser}/node_modules/mime-types/README.md +0 -0
- /package/node_modules/{type-is → body-parser}/node_modules/mime-types/index.js +0 -0
- /package/node_modules/{type-is → body-parser}/node_modules/mime-types/mimeScore.js +0 -0
- /package/node_modules/{type-is → body-parser}/node_modules/mime-types/package.json +0 -0
- /package/node_modules/{type-is → body-parser/node_modules/type-is}/HISTORY.md +0 -0
- /package/node_modules/{type-is → body-parser/node_modules/type-is}/LICENSE +0 -0
- /package/node_modules/{type-is → body-parser/node_modules/type-is}/README.md +0 -0
- /package/node_modules/{type-is → body-parser/node_modules/type-is}/index.js +0 -0
- /package/node_modules/{type-is → body-parser/node_modules/type-is}/package.json +0 -0
package/dist/server/index.mjs
CHANGED
|
@@ -3,14 +3,10 @@ import { ListToolsRequestSchema, CallToolRequestSchema } from "@modelcontextprot
|
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
6
|
-
import { TokenTextSplitter } from "@langchain/textsplitters";
|
|
7
|
-
import { PromptTemplate } from "@langchain/core/prompts";
|
|
8
|
-
import { ChatOpenAI } from "@langchain/openai";
|
|
9
6
|
import { Innertube } from "youtubei.js";
|
|
10
7
|
import { ProxyAgent, fetch as fetch$1 } from "undici";
|
|
11
8
|
const FetchTranscriptSchema = z.object({
|
|
12
|
-
videoId: z.string().min(1, "Video ID or URL is required")
|
|
13
|
-
generateReadable: z.boolean().optional().default(false)
|
|
9
|
+
videoId: z.string().min(1, "Video ID or URL is required")
|
|
14
10
|
});
|
|
15
11
|
const ListTranscriptsSchema = z.object({
|
|
16
12
|
page: z.number().int().min(1).optional().default(1),
|
|
@@ -67,31 +63,26 @@ function extractYouTubeID(urlOrID) {
|
|
|
67
63
|
}
|
|
68
64
|
const fetchTranscriptTool = {
|
|
69
65
|
name: "fetch_transcript",
|
|
70
|
-
description: "Fetch a transcript from YouTube for a given video ID or URL.
|
|
66
|
+
description: "Fetch a transcript from YouTube for a given video ID or URL. The transcript is saved to the database for future retrieval.",
|
|
71
67
|
inputSchema: {
|
|
72
68
|
type: "object",
|
|
73
69
|
properties: {
|
|
74
70
|
videoId: {
|
|
75
71
|
type: "string",
|
|
76
72
|
description: 'YouTube video ID (e.g., "dQw4w9WgXcQ") or full YouTube URL'
|
|
77
|
-
},
|
|
78
|
-
generateReadable: {
|
|
79
|
-
type: "boolean",
|
|
80
|
-
description: "If true, uses AI to add punctuation and formatting to make the transcript more readable. Requires OpenAI API key configuration.",
|
|
81
|
-
default: false
|
|
82
73
|
}
|
|
83
74
|
},
|
|
84
75
|
required: ["videoId"]
|
|
85
76
|
}
|
|
86
77
|
};
|
|
87
|
-
async function handleFetchTranscript(
|
|
78
|
+
async function handleFetchTranscript(strapi, args) {
|
|
88
79
|
const validatedArgs = validateToolInput("fetch_transcript", args);
|
|
89
|
-
const { videoId: videoIdOrUrl
|
|
80
|
+
const { videoId: videoIdOrUrl } = validatedArgs;
|
|
90
81
|
const videoId = extractYouTubeID(videoIdOrUrl);
|
|
91
82
|
if (!videoId) {
|
|
92
83
|
throw new Error(`Invalid YouTube video ID or URL: "${videoIdOrUrl}". Please provide a valid 11-character video ID or YouTube URL.`);
|
|
93
84
|
}
|
|
94
|
-
const service2 =
|
|
85
|
+
const service2 = strapi.plugin("yt-transcript-strapi-plugin").service("service");
|
|
95
86
|
const existingTranscript = await service2.findTranscript(videoId);
|
|
96
87
|
if (existingTranscript) {
|
|
97
88
|
return {
|
|
@@ -121,14 +112,6 @@ async function handleFetchTranscript(strapi2, args) {
|
|
|
121
112
|
fullTranscript: transcriptData.fullTranscript,
|
|
122
113
|
transcriptWithTimeCodes: transcriptData.transcriptWithTimeCodes
|
|
123
114
|
};
|
|
124
|
-
if (generateReadable && transcriptData.fullTranscript) {
|
|
125
|
-
try {
|
|
126
|
-
const readableTranscript = await service2.generateHumanReadableTranscript(transcriptData.fullTranscript);
|
|
127
|
-
payload.readableTranscript = readableTranscript;
|
|
128
|
-
} catch (error) {
|
|
129
|
-
strapi2.log.warn("[yt-transcript-mcp] Failed to generate readable transcript:", error);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
115
|
const savedTranscript = await service2.saveTranscript(payload);
|
|
133
116
|
return {
|
|
134
117
|
content: [
|
|
@@ -172,17 +155,17 @@ const listTranscriptsTool = {
|
|
|
172
155
|
required: []
|
|
173
156
|
}
|
|
174
157
|
};
|
|
175
|
-
async function handleListTranscripts(
|
|
158
|
+
async function handleListTranscripts(strapi, args) {
|
|
176
159
|
const validatedArgs = validateToolInput("list_transcripts", args);
|
|
177
160
|
const { page, pageSize, sort } = validatedArgs;
|
|
178
161
|
const start = (page - 1) * pageSize;
|
|
179
|
-
const transcripts = await
|
|
162
|
+
const transcripts = await strapi.documents("plugin::yt-transcript-strapi-plugin.transcript").findMany({
|
|
180
163
|
sort,
|
|
181
164
|
limit: pageSize,
|
|
182
165
|
start,
|
|
183
166
|
fields: ["id", "documentId", "title", "videoId", "createdAt", "updatedAt"]
|
|
184
167
|
});
|
|
185
|
-
const allTranscripts = await
|
|
168
|
+
const allTranscripts = await strapi.documents("plugin::yt-transcript-strapi-plugin.transcript").findMany({});
|
|
186
169
|
const total = allTranscripts.length;
|
|
187
170
|
return {
|
|
188
171
|
content: [
|
|
@@ -219,14 +202,14 @@ const getTranscriptTool = {
|
|
|
219
202
|
required: ["videoId"]
|
|
220
203
|
}
|
|
221
204
|
};
|
|
222
|
-
async function handleGetTranscript(
|
|
205
|
+
async function handleGetTranscript(strapi, args) {
|
|
223
206
|
const validatedArgs = validateToolInput("get_transcript", args);
|
|
224
207
|
const { videoId: videoIdOrUrl } = validatedArgs;
|
|
225
208
|
const videoId = extractYouTubeID(videoIdOrUrl);
|
|
226
209
|
if (!videoId) {
|
|
227
210
|
throw new Error(`Invalid YouTube video ID or URL: "${videoIdOrUrl}". Please provide a valid 11-character video ID or YouTube URL.`);
|
|
228
211
|
}
|
|
229
|
-
const service2 =
|
|
212
|
+
const service2 = strapi.plugin("yt-transcript-strapi-plugin").service("service");
|
|
230
213
|
const transcript2 = await service2.findTranscript(videoId);
|
|
231
214
|
if (!transcript2) {
|
|
232
215
|
return {
|
|
@@ -311,11 +294,10 @@ function truncateText(text, maxLength) {
|
|
|
311
294
|
function truncateTranscripts(transcripts) {
|
|
312
295
|
return transcripts.map((transcript2) => ({
|
|
313
296
|
...transcript2,
|
|
314
|
-
fullTranscript: truncateText(transcript2.fullTranscript, TRANSCRIPT_PREVIEW_LENGTH)
|
|
315
|
-
readableTranscript: truncateText(transcript2.readableTranscript, TRANSCRIPT_PREVIEW_LENGTH)
|
|
297
|
+
fullTranscript: truncateText(transcript2.fullTranscript, TRANSCRIPT_PREVIEW_LENGTH)
|
|
316
298
|
}));
|
|
317
299
|
}
|
|
318
|
-
async function handleFindTranscripts(
|
|
300
|
+
async function handleFindTranscripts(strapi, args) {
|
|
319
301
|
const validatedArgs = validateToolInput("find_transcripts", args);
|
|
320
302
|
const { query, videoId, title, includeFullContent, page, pageSize, sort } = validatedArgs;
|
|
321
303
|
const start = (page - 1) * pageSize;
|
|
@@ -330,17 +312,16 @@ async function handleFindTranscripts(strapi2, args) {
|
|
|
330
312
|
filters.$or = [
|
|
331
313
|
{ title: { $containsi: query } },
|
|
332
314
|
{ videoId: { $containsi: query } },
|
|
333
|
-
{ fullTranscript: { $containsi: query } }
|
|
334
|
-
{ readableTranscript: { $containsi: query } }
|
|
315
|
+
{ fullTranscript: { $containsi: query } }
|
|
335
316
|
];
|
|
336
317
|
}
|
|
337
|
-
const transcripts = await
|
|
318
|
+
const transcripts = await strapi.documents("plugin::yt-transcript-strapi-plugin.transcript").findMany({
|
|
338
319
|
filters,
|
|
339
320
|
sort,
|
|
340
321
|
limit: pageSize,
|
|
341
322
|
start
|
|
342
323
|
});
|
|
343
|
-
const allMatching = await
|
|
324
|
+
const allMatching = await strapi.documents("plugin::yt-transcript-strapi-plugin.transcript").findMany({
|
|
344
325
|
filters
|
|
345
326
|
});
|
|
346
327
|
const total = allMatching.length;
|
|
@@ -384,7 +365,7 @@ const toolHandlers = {
|
|
|
384
365
|
get_transcript: handleGetTranscript,
|
|
385
366
|
find_transcripts: handleFindTranscripts
|
|
386
367
|
};
|
|
387
|
-
async function handleToolCall(
|
|
368
|
+
async function handleToolCall(strapi, request) {
|
|
388
369
|
const { name, arguments: args } = request.params;
|
|
389
370
|
const handler = toolHandlers[name];
|
|
390
371
|
if (!handler) {
|
|
@@ -392,13 +373,13 @@ async function handleToolCall(strapi2, request) {
|
|
|
392
373
|
}
|
|
393
374
|
const startTime = Date.now();
|
|
394
375
|
try {
|
|
395
|
-
const result = await handler(
|
|
376
|
+
const result = await handler(strapi, args || {});
|
|
396
377
|
const duration = Date.now() - startTime;
|
|
397
|
-
|
|
378
|
+
strapi.log.debug(`[yt-transcript-mcp] Tool ${name} executed successfully in ${duration}ms`);
|
|
398
379
|
return result;
|
|
399
380
|
} catch (error) {
|
|
400
381
|
const duration = Date.now() - startTime;
|
|
401
|
-
|
|
382
|
+
strapi.log.error(`[yt-transcript-mcp] Tool ${name} failed after ${duration}ms`, {
|
|
402
383
|
error: error instanceof Error ? error.message : String(error)
|
|
403
384
|
});
|
|
404
385
|
return {
|
|
@@ -419,7 +400,7 @@ async function handleToolCall(strapi2, request) {
|
|
|
419
400
|
};
|
|
420
401
|
}
|
|
421
402
|
}
|
|
422
|
-
function createMcpServer(
|
|
403
|
+
function createMcpServer(strapi) {
|
|
423
404
|
const server = new Server(
|
|
424
405
|
{
|
|
425
406
|
name: "yt-transcript-mcp",
|
|
@@ -432,28 +413,28 @@ function createMcpServer(strapi2) {
|
|
|
432
413
|
}
|
|
433
414
|
);
|
|
434
415
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
435
|
-
|
|
416
|
+
strapi.log.debug("[yt-transcript-mcp] Listing tools");
|
|
436
417
|
return { tools };
|
|
437
418
|
});
|
|
438
419
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
439
|
-
|
|
440
|
-
return handleToolCall(
|
|
420
|
+
strapi.log.debug(`[yt-transcript-mcp] Tool call: ${request.params.name}`);
|
|
421
|
+
return handleToolCall(strapi, request);
|
|
441
422
|
});
|
|
442
|
-
|
|
423
|
+
strapi.log.info("[yt-transcript-mcp] MCP server created with tools:", {
|
|
443
424
|
tools: tools.map((t) => t.name)
|
|
444
425
|
});
|
|
445
426
|
return server;
|
|
446
427
|
}
|
|
447
|
-
const bootstrap = async ({ strapi
|
|
448
|
-
const plugin =
|
|
449
|
-
plugin.createMcpServer = () => createMcpServer(
|
|
428
|
+
const bootstrap = async ({ strapi }) => {
|
|
429
|
+
const plugin = strapi.plugin("yt-transcript-strapi-plugin");
|
|
430
|
+
plugin.createMcpServer = () => createMcpServer(strapi);
|
|
450
431
|
plugin.sessions = /* @__PURE__ */ new Map();
|
|
451
|
-
|
|
452
|
-
|
|
432
|
+
strapi.log.info("[yt-transcript-mcp] MCP plugin initialized");
|
|
433
|
+
strapi.log.info("[yt-transcript-mcp] MCP endpoint available at: /api/yt-transcript-strapi-plugin/mcp");
|
|
453
434
|
};
|
|
454
|
-
const destroy = ({ strapi
|
|
435
|
+
const destroy = ({ strapi }) => {
|
|
455
436
|
};
|
|
456
|
-
const register = ({ strapi
|
|
437
|
+
const register = ({ strapi }) => {
|
|
457
438
|
};
|
|
458
439
|
const config = {
|
|
459
440
|
default: {
|
|
@@ -512,9 +493,6 @@ const attributes = {
|
|
|
512
493
|
},
|
|
513
494
|
transcriptWithTimeCodes: {
|
|
514
495
|
type: "json"
|
|
515
|
-
},
|
|
516
|
-
readableTranscript: {
|
|
517
|
-
type: "richtext"
|
|
518
496
|
}
|
|
519
497
|
};
|
|
520
498
|
const schema = {
|
|
@@ -531,41 +509,34 @@ const transcript = {
|
|
|
531
509
|
const contentTypes = {
|
|
532
510
|
transcript
|
|
533
511
|
};
|
|
534
|
-
const controller = ({ strapi
|
|
512
|
+
const controller = ({ strapi }) => ({
|
|
535
513
|
async getTranscript(ctx) {
|
|
536
514
|
const videoId = extractYouTubeID(ctx.params.videoId);
|
|
537
515
|
if (!videoId) {
|
|
538
516
|
return ctx.body = { error: "Invalid YouTube URL or ID", data: null };
|
|
539
517
|
}
|
|
540
|
-
const found = await
|
|
518
|
+
const found = await strapi.plugin("yt-transcript-strapi-plugin").service("service").findTranscript(videoId);
|
|
541
519
|
if (found) {
|
|
542
520
|
return ctx.body = { data: found };
|
|
543
521
|
}
|
|
544
|
-
const transcriptData = await
|
|
545
|
-
let readableTranscript = null;
|
|
546
|
-
try {
|
|
547
|
-
readableTranscript = await strapi2.plugin("yt-transcript-strapi-plugin").service("service").generateHumanReadableTranscript(transcriptData.fullTranscript);
|
|
548
|
-
} catch (error) {
|
|
549
|
-
strapi2.log.debug("[yt-transcript] Readable transcript generation skipped");
|
|
550
|
-
}
|
|
522
|
+
const transcriptData = await strapi.plugin("yt-transcript-strapi-plugin").service("service").getTranscript(videoId);
|
|
551
523
|
const payload = {
|
|
552
524
|
videoId,
|
|
553
525
|
title: transcriptData?.title || "No title found",
|
|
554
526
|
fullTranscript: transcriptData?.fullTranscript,
|
|
555
|
-
transcriptWithTimeCodes: transcriptData?.transcriptWithTimeCodes
|
|
556
|
-
readableTranscript
|
|
527
|
+
transcriptWithTimeCodes: transcriptData?.transcriptWithTimeCodes
|
|
557
528
|
};
|
|
558
|
-
const transcript2 = await
|
|
529
|
+
const transcript2 = await strapi.plugin("yt-transcript-strapi-plugin").service("service").saveTranscript(payload);
|
|
559
530
|
ctx.body = { data: transcript2 };
|
|
560
531
|
}
|
|
561
532
|
});
|
|
562
|
-
const mcpController = ({ strapi
|
|
533
|
+
const mcpController = ({ strapi }) => ({
|
|
563
534
|
/**
|
|
564
535
|
* Handle MCP requests (POST, GET, DELETE)
|
|
565
536
|
* Creates a new server+transport per session for proper isolation
|
|
566
537
|
*/
|
|
567
538
|
async handle(ctx) {
|
|
568
|
-
const plugin =
|
|
539
|
+
const plugin = strapi.plugin("yt-transcript-strapi-plugin");
|
|
569
540
|
if (!plugin.createMcpServer) {
|
|
570
541
|
ctx.status = 503;
|
|
571
542
|
ctx.body = {
|
|
@@ -585,12 +556,12 @@ const mcpController = ({ strapi: strapi2 }) => ({
|
|
|
585
556
|
await server.connect(transport);
|
|
586
557
|
session = { server, transport, createdAt: Date.now() };
|
|
587
558
|
plugin.sessions.set(sessionId, session);
|
|
588
|
-
|
|
559
|
+
strapi.log.debug(`[yt-transcript-mcp] New session created: ${sessionId}`);
|
|
589
560
|
}
|
|
590
561
|
await session.transport.handleRequest(ctx.req, ctx.res, ctx.request.body);
|
|
591
562
|
ctx.respond = false;
|
|
592
563
|
} catch (error) {
|
|
593
|
-
|
|
564
|
+
strapi.log.error("[yt-transcript-mcp] Error handling MCP request", {
|
|
594
565
|
error: error instanceof Error ? error.message : String(error),
|
|
595
566
|
method: ctx.method,
|
|
596
567
|
path: ctx.path
|
|
@@ -670,18 +641,6 @@ const routes = {
|
|
|
670
641
|
routes: [...admin]
|
|
671
642
|
}
|
|
672
643
|
};
|
|
673
|
-
async function initializeModel({
|
|
674
|
-
openAIApiKey,
|
|
675
|
-
model,
|
|
676
|
-
temp
|
|
677
|
-
}) {
|
|
678
|
-
return new ChatOpenAI({
|
|
679
|
-
temperature: temp,
|
|
680
|
-
openAIApiKey,
|
|
681
|
-
modelName: model,
|
|
682
|
-
maxTokens: 1e3
|
|
683
|
-
});
|
|
684
|
-
}
|
|
685
644
|
function isRequestLike(input) {
|
|
686
645
|
return typeof input === "object" && input !== null && "url" in input && typeof input.url === "string" && "method" in input;
|
|
687
646
|
}
|
|
@@ -824,49 +783,14 @@ const fetchTranscript = async (videoId, options2) => {
|
|
|
824
783
|
);
|
|
825
784
|
}
|
|
826
785
|
};
|
|
827
|
-
|
|
828
|
-
const punctuationPrompt = PromptTemplate.fromTemplate(
|
|
829
|
-
"Add proper punctuation and capitalization to the following text chunk:\n\n{chunk}"
|
|
830
|
-
);
|
|
831
|
-
const punctuationChain = punctuationPrompt.pipe(model);
|
|
832
|
-
const processedChunks = await Promise.all(
|
|
833
|
-
chunks.map(async (chunk) => {
|
|
834
|
-
const result = await punctuationChain.invoke({ chunk });
|
|
835
|
-
return result.content;
|
|
836
|
-
})
|
|
837
|
-
);
|
|
838
|
-
return processedChunks.join(" ");
|
|
839
|
-
}
|
|
840
|
-
async function generateModifiedTranscript(rawTranscript) {
|
|
841
|
-
const pluginSettings = await strapi.config.get(
|
|
842
|
-
"plugin::yt-transcript-strapi-plugin"
|
|
843
|
-
);
|
|
844
|
-
if (!pluginSettings.openAIApiKey || !pluginSettings.model || !pluginSettings.temp || !pluginSettings.maxTokens) {
|
|
845
|
-
throw new Error("Missing required configuration for YTTranscript");
|
|
846
|
-
}
|
|
847
|
-
const chatModel = await initializeModel({
|
|
848
|
-
openAIApiKey: pluginSettings.openAIApiKey,
|
|
849
|
-
model: pluginSettings.model,
|
|
850
|
-
temp: pluginSettings.temp,
|
|
851
|
-
maxTokens: pluginSettings.maxTokens
|
|
852
|
-
});
|
|
853
|
-
const splitter = new TokenTextSplitter({
|
|
854
|
-
chunkSize: 1e3,
|
|
855
|
-
chunkOverlap: 200
|
|
856
|
-
});
|
|
857
|
-
const transcriptChunks = await splitter.createDocuments([rawTranscript]);
|
|
858
|
-
const chunkTexts = transcriptChunks.map((chunk) => chunk.pageContent);
|
|
859
|
-
const modifiedTranscript = await processTextChunks(chunkTexts, chatModel);
|
|
860
|
-
return modifiedTranscript;
|
|
861
|
-
}
|
|
862
|
-
const service = ({ strapi: strapi2 }) => ({
|
|
786
|
+
const service = ({ strapi }) => ({
|
|
863
787
|
async getTranscript(identifier) {
|
|
864
788
|
const youtubeIdRegex = /^[a-zA-Z0-9_-]{11}$/;
|
|
865
789
|
const isValid = youtubeIdRegex.test(identifier);
|
|
866
790
|
if (!isValid) {
|
|
867
791
|
return { error: "Invalid video ID", data: null };
|
|
868
792
|
}
|
|
869
|
-
const pluginSettings = await
|
|
793
|
+
const pluginSettings = await strapi.config.get(
|
|
870
794
|
"plugin::yt-transcript-strapi-plugin"
|
|
871
795
|
);
|
|
872
796
|
const transcriptData = await fetchTranscript(identifier, {
|
|
@@ -879,20 +803,16 @@ const service = ({ strapi: strapi2 }) => ({
|
|
|
879
803
|
};
|
|
880
804
|
},
|
|
881
805
|
async saveTranscript(payload) {
|
|
882
|
-
return await
|
|
806
|
+
return await strapi.documents("plugin::yt-transcript-strapi-plugin.transcript").create({
|
|
883
807
|
data: payload
|
|
884
808
|
});
|
|
885
809
|
},
|
|
886
810
|
async findTranscript(videoId) {
|
|
887
|
-
const transcriptData = await
|
|
811
|
+
const transcriptData = await strapi.documents("plugin::yt-transcript-strapi-plugin.transcript").findFirst({
|
|
888
812
|
filters: { videoId }
|
|
889
813
|
});
|
|
890
814
|
if (!transcriptData) return null;
|
|
891
815
|
return transcriptData;
|
|
892
|
-
},
|
|
893
|
-
async generateHumanReadableTranscript(transcript2) {
|
|
894
|
-
const modifiedTranscript = await generateModifiedTranscript(transcript2);
|
|
895
|
-
return modifiedTranscript;
|
|
896
816
|
}
|
|
897
817
|
});
|
|
898
818
|
const services = {
|
|
@@ -94,7 +94,6 @@ declare const _default: {
|
|
|
94
94
|
}>;
|
|
95
95
|
saveTranscript(payload: Record<string, unknown>): Promise<import("@strapi/types/dist/modules/documents").AnyDocument>;
|
|
96
96
|
findTranscript(videoId: string): Promise<import("@strapi/types/dist/modules/documents").AnyDocument>;
|
|
97
|
-
generateHumanReadableTranscript(transcript: string): Promise<string>;
|
|
98
97
|
};
|
|
99
98
|
};
|
|
100
99
|
contentTypes: {
|
|
@@ -131,9 +130,6 @@ declare const _default: {
|
|
|
131
130
|
transcriptWithTimeCodes: {
|
|
132
131
|
type: string;
|
|
133
132
|
};
|
|
134
|
-
readableTranscript: {
|
|
135
|
-
type: string;
|
|
136
|
-
};
|
|
137
133
|
};
|
|
138
134
|
};
|
|
139
135
|
};
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
export declare const FetchTranscriptSchema: z.ZodObject<{
|
|
3
3
|
videoId: z.ZodString;
|
|
4
|
-
generateReadable: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
5
4
|
}, "strip", z.ZodTypeAny, {
|
|
6
5
|
videoId?: string;
|
|
7
|
-
generateReadable?: boolean;
|
|
8
6
|
}, {
|
|
9
7
|
videoId?: string;
|
|
10
|
-
generateReadable?: boolean;
|
|
11
8
|
}>;
|
|
12
9
|
export declare const ListTranscriptsSchema: z.ZodObject<{
|
|
13
10
|
page: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
@@ -61,13 +58,10 @@ export type FindTranscriptsInput = z.infer<typeof FindTranscriptsSchema>;
|
|
|
61
58
|
export declare const ToolSchemas: {
|
|
62
59
|
readonly fetch_transcript: z.ZodObject<{
|
|
63
60
|
videoId: z.ZodString;
|
|
64
|
-
generateReadable: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
65
61
|
}, "strip", z.ZodTypeAny, {
|
|
66
62
|
videoId?: string;
|
|
67
|
-
generateReadable?: boolean;
|
|
68
63
|
}, {
|
|
69
64
|
videoId?: string;
|
|
70
|
-
generateReadable?: boolean;
|
|
71
65
|
}>;
|
|
72
66
|
readonly list_transcripts: z.ZodObject<{
|
|
73
67
|
page: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import type { Core } from '@strapi/strapi';
|
|
2
2
|
export declare const tools: ({
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: "object";
|
|
7
|
+
properties: {
|
|
8
|
+
videoId: {
|
|
9
|
+
type: string;
|
|
10
|
+
description: string;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
required: string[];
|
|
14
|
+
};
|
|
15
|
+
} | {
|
|
3
16
|
name: string;
|
|
4
17
|
description: string;
|
|
5
18
|
inputSchema: {
|
|
@@ -23,19 +36,6 @@ export declare const tools: ({
|
|
|
23
36
|
};
|
|
24
37
|
required: any[];
|
|
25
38
|
};
|
|
26
|
-
} | {
|
|
27
|
-
name: string;
|
|
28
|
-
description: string;
|
|
29
|
-
inputSchema: {
|
|
30
|
-
type: "object";
|
|
31
|
-
properties: {
|
|
32
|
-
videoId: {
|
|
33
|
-
type: string;
|
|
34
|
-
description: string;
|
|
35
|
-
};
|
|
36
|
-
};
|
|
37
|
-
required: string[];
|
|
38
|
-
};
|
|
39
39
|
})[];
|
|
40
40
|
/**
|
|
41
41
|
* Handle a tool call by delegating to the appropriate handler
|
|
@@ -17,7 +17,6 @@ declare const _default: {
|
|
|
17
17
|
}>;
|
|
18
18
|
saveTranscript(payload: Record<string, unknown>): Promise<import("@strapi/types/dist/modules/documents").AnyDocument>;
|
|
19
19
|
findTranscript(videoId: string): Promise<import("@strapi/types/dist/modules/documents").AnyDocument>;
|
|
20
|
-
generateHumanReadableTranscript(transcript: string): Promise<string>;
|
|
21
20
|
};
|
|
22
21
|
};
|
|
23
22
|
export default _default;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { Core } from '@strapi/strapi';
|
|
2
|
-
export declare function generateModifiedTranscript(rawTranscript: string): Promise<string>;
|
|
3
2
|
declare const service: ({ strapi }: {
|
|
4
3
|
strapi: Core.Strapi;
|
|
5
4
|
}) => {
|
|
@@ -18,6 +17,5 @@ declare const service: ({ strapi }: {
|
|
|
18
17
|
}>;
|
|
19
18
|
saveTranscript(payload: Record<string, unknown>): Promise<import("@strapi/types/dist/modules/documents").AnyDocument>;
|
|
20
19
|
findTranscript(videoId: string): Promise<import("@strapi/types/dist/modules/documents").AnyDocument>;
|
|
21
|
-
generateHumanReadableTranscript(transcript: string): Promise<string>;
|
|
22
20
|
};
|
|
23
21
|
export default service;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
1.1.0 / 2019-04-24
|
|
2
|
+
==================
|
|
3
|
+
|
|
4
|
+
* Add `test(string)` function
|
|
5
|
+
|
|
6
|
+
1.0.2 / 2019-04-19
|
|
7
|
+
==================
|
|
8
|
+
|
|
9
|
+
* Fix JSDoc comment for `parse` function
|
|
10
|
+
|
|
11
|
+
1.0.1 / 2018-10-20
|
|
12
|
+
==================
|
|
13
|
+
|
|
14
|
+
* Remove left over `parameters` property from class
|
|
15
|
+
|
|
16
|
+
1.0.0 / 2018-10-20
|
|
17
|
+
==================
|
|
18
|
+
|
|
19
|
+
This major release brings the module back to it's RFC 6838 roots. If you want
|
|
20
|
+
a module to parse the `Content-Type` or similar HTTP headers, use the
|
|
21
|
+
`content-type` module instead.
|
|
22
|
+
|
|
23
|
+
* Drop support for Node.js below 0.8
|
|
24
|
+
* Remove parameter handling, which is outside RFC 6838 scope
|
|
25
|
+
* Remove `parse(req)` and `parse(res)` signatures
|
|
26
|
+
* perf: enable strict mode
|
|
27
|
+
* perf: use a class for object creation
|
|
28
|
+
|
|
29
|
+
0.3.0 / 2014-09-07
|
|
30
|
+
==================
|
|
31
|
+
|
|
32
|
+
* Support Node.js 0.6
|
|
33
|
+
* Throw error when parameter format invalid on parse
|
|
34
|
+
|
|
35
|
+
0.2.0 / 2014-06-18
|
|
36
|
+
==================
|
|
37
|
+
|
|
38
|
+
* Add `typer.format()` to format media types
|
|
39
|
+
|
|
40
|
+
0.1.0 / 2014-06-17
|
|
41
|
+
==================
|
|
42
|
+
|
|
43
|
+
* Accept `req` as argument to `parse`
|
|
44
|
+
* Accept `res` as argument to `parse`
|
|
45
|
+
* Parse media type with extra LWS between type and first parameter
|
|
46
|
+
|
|
47
|
+
0.0.0 / 2014-06-13
|
|
48
|
+
==================
|
|
49
|
+
|
|
50
|
+
* Initial implementation
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
(The MIT License)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2014-2017 Douglas Christopher Wilson
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|