@dxos/plugin-youtube 0.8.3
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/LICENSE +21 -0
- package/dist/lib/browser/ChannelArticle-CDQR4BBY.mjs +90 -0
- package/dist/lib/browser/ChannelArticle-CDQR4BBY.mjs.map +7 -0
- package/dist/lib/browser/ChannelSettings-ZYUNW3VS.mjs +28 -0
- package/dist/lib/browser/ChannelSettings-ZYUNW3VS.mjs.map +7 -0
- package/dist/lib/browser/VideoArticle-FC4A6E7B.mjs +76 -0
- package/dist/lib/browser/VideoArticle-FC4A6E7B.mjs.map +7 -0
- package/dist/lib/browser/VideoCard-CCPXDCB7.mjs +64 -0
- package/dist/lib/browser/VideoCard-CCPXDCB7.mjs.map +7 -0
- package/dist/lib/browser/app-graph-builder-MJY6A6SN.mjs +195 -0
- package/dist/lib/browser/app-graph-builder-MJY6A6SN.mjs.map +7 -0
- package/dist/lib/browser/blueprint-definition-FRYUYJ22.mjs +22 -0
- package/dist/lib/browser/blueprint-definition-FRYUYJ22.mjs.map +7 -0
- package/dist/lib/browser/blueprints/index.mjs +13 -0
- package/dist/lib/browser/blueprints/index.mjs.map +7 -0
- package/dist/lib/browser/chunk-C26XKDK2.mjs +355 -0
- package/dist/lib/browser/chunk-C26XKDK2.mjs.map +7 -0
- package/dist/lib/browser/chunk-DFRSBBSO.mjs +21 -0
- package/dist/lib/browser/chunk-DFRSBBSO.mjs.map +7 -0
- package/dist/lib/browser/chunk-GFRR4TTX.mjs +72 -0
- package/dist/lib/browser/chunk-GFRR4TTX.mjs.map +7 -0
- package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
- package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +7 -0
- package/dist/lib/browser/chunk-MUE22YUM.mjs +57 -0
- package/dist/lib/browser/chunk-MUE22YUM.mjs.map +7 -0
- package/dist/lib/browser/chunk-P67QEKBQ.mjs +72 -0
- package/dist/lib/browser/chunk-P67QEKBQ.mjs.map +7 -0
- package/dist/lib/browser/chunk-YMDT37TA.mjs +62 -0
- package/dist/lib/browser/chunk-YMDT37TA.mjs.map +7 -0
- package/dist/lib/browser/chunk-Z3DGTMKC.mjs +8 -0
- package/dist/lib/browser/chunk-Z3DGTMKC.mjs.map +7 -0
- package/dist/lib/browser/clear-synced-videos-EVMJIZPD.mjs +66 -0
- package/dist/lib/browser/clear-synced-videos-EVMJIZPD.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +153 -0
- package/dist/lib/browser/index.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -0
- package/dist/lib/browser/react-surface-EDA5VYDC.mjs +77 -0
- package/dist/lib/browser/react-surface-EDA5VYDC.mjs.map +7 -0
- package/dist/lib/browser/sync-423Q4BDD.mjs +360 -0
- package/dist/lib/browser/sync-423Q4BDD.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +14 -0
- package/dist/lib/browser/types/index.mjs.map +7 -0
- package/dist/lib/node-esm/ChannelArticle-GQ64BO7V.mjs +91 -0
- package/dist/lib/node-esm/ChannelArticle-GQ64BO7V.mjs.map +7 -0
- package/dist/lib/node-esm/ChannelSettings-DM2HWNKO.mjs +29 -0
- package/dist/lib/node-esm/ChannelSettings-DM2HWNKO.mjs.map +7 -0
- package/dist/lib/node-esm/VideoArticle-WLTWZO3K.mjs +77 -0
- package/dist/lib/node-esm/VideoArticle-WLTWZO3K.mjs.map +7 -0
- package/dist/lib/node-esm/VideoCard-FOWQZK75.mjs +65 -0
- package/dist/lib/node-esm/VideoCard-FOWQZK75.mjs.map +7 -0
- package/dist/lib/node-esm/app-graph-builder-IU5TBAXN.mjs +196 -0
- package/dist/lib/node-esm/app-graph-builder-IU5TBAXN.mjs.map +7 -0
- package/dist/lib/node-esm/blueprint-definition-W264MZ3D.mjs +23 -0
- package/dist/lib/node-esm/blueprint-definition-W264MZ3D.mjs.map +7 -0
- package/dist/lib/node-esm/blueprints/index.mjs +14 -0
- package/dist/lib/node-esm/blueprints/index.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-5KNC2JMP.mjs +58 -0
- package/dist/lib/node-esm/chunk-5KNC2JMP.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-6BUJ2DQX.mjs +73 -0
- package/dist/lib/node-esm/chunk-6BUJ2DQX.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-CX6MV3QM.mjs +23 -0
- package/dist/lib/node-esm/chunk-CX6MV3QM.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-CZSLL3XQ.mjs +63 -0
- package/dist/lib/node-esm/chunk-CZSLL3XQ.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-JM5SBBP5.mjs +356 -0
- package/dist/lib/node-esm/chunk-JM5SBBP5.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-JSGRZMG3.mjs +73 -0
- package/dist/lib/node-esm/chunk-JSGRZMG3.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-M4S6BE47.mjs +10 -0
- package/dist/lib/node-esm/chunk-M4S6BE47.mjs.map +7 -0
- package/dist/lib/node-esm/clear-synced-videos-5UCH6XHL.mjs +67 -0
- package/dist/lib/node-esm/clear-synced-videos-5UCH6XHL.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +154 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/lib/node-esm/react-surface-5DJAQPHJ.mjs +78 -0
- package/dist/lib/node-esm/react-surface-5DJAQPHJ.mjs.map +7 -0
- package/dist/lib/node-esm/sync-CEF5DX2J.mjs +361 -0
- package/dist/lib/node-esm/sync-CEF5DX2J.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +15 -0
- package/dist/lib/node-esm/types/index.mjs.map +7 -0
- package/dist/types/src/YouTubePlugin.d.ts +3 -0
- package/dist/types/src/YouTubePlugin.d.ts.map +1 -0
- package/dist/types/src/blueprints/index.d.ts +3 -0
- package/dist/types/src/blueprints/index.d.ts.map +1 -0
- package/dist/types/src/blueprints/youtube.d.ts +4 -0
- package/dist/types/src/blueprints/youtube.d.ts.map +1 -0
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +6 -0
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/app-graph-builder/index.d.ts +3 -0
- package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/blueprint-definition/blueprint-definition.d.ts +6 -0
- package/dist/types/src/capabilities/blueprint-definition/blueprint-definition.d.ts.map +1 -0
- package/dist/types/src/capabilities/blueprint-definition/index.d.ts +3 -0
- package/dist/types/src/capabilities/blueprint-definition/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +4 -0
- package/dist/types/src/capabilities/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface/index.d.ts +3 -0
- package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts +5 -0
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -0
- package/dist/types/src/containers/ChannelArticle/ChannelArticle.d.ts +8 -0
- package/dist/types/src/containers/ChannelArticle/ChannelArticle.d.ts.map +1 -0
- package/dist/types/src/containers/ChannelArticle/index.d.ts +3 -0
- package/dist/types/src/containers/ChannelArticle/index.d.ts.map +1 -0
- package/dist/types/src/containers/ChannelSettings/ChannelSettings.d.ts +7 -0
- package/dist/types/src/containers/ChannelSettings/ChannelSettings.d.ts.map +1 -0
- package/dist/types/src/containers/ChannelSettings/index.d.ts +3 -0
- package/dist/types/src/containers/ChannelSettings/index.d.ts.map +1 -0
- package/dist/types/src/containers/VideoArticle/VideoArticle.d.ts +11 -0
- package/dist/types/src/containers/VideoArticle/VideoArticle.d.ts.map +1 -0
- package/dist/types/src/containers/VideoArticle/index.d.ts +3 -0
- package/dist/types/src/containers/VideoArticle/index.d.ts.map +1 -0
- package/dist/types/src/containers/VideoCard/VideoCard.d.ts +9 -0
- package/dist/types/src/containers/VideoCard/VideoCard.d.ts.map +1 -0
- package/dist/types/src/containers/VideoCard/index.d.ts +3 -0
- package/dist/types/src/containers/VideoCard/index.d.ts.map +1 -0
- package/dist/types/src/containers/index.d.ts +11 -0
- package/dist/types/src/containers/index.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +4 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/meta.d.ts +3 -0
- package/dist/types/src/meta.d.ts.map +1 -0
- package/dist/types/src/operations/apis/index.d.ts +2 -0
- package/dist/types/src/operations/apis/index.d.ts.map +1 -0
- package/dist/types/src/operations/apis/youtube/api.d.ts +251 -0
- package/dist/types/src/operations/apis/youtube/api.d.ts.map +1 -0
- package/dist/types/src/operations/apis/youtube/index.d.ts +3 -0
- package/dist/types/src/operations/apis/youtube/index.d.ts.map +1 -0
- package/dist/types/src/operations/apis/youtube/types.d.ts +493 -0
- package/dist/types/src/operations/apis/youtube/types.d.ts.map +1 -0
- package/dist/types/src/operations/clear-synced-videos.d.ts +5 -0
- package/dist/types/src/operations/clear-synced-videos.d.ts.map +1 -0
- package/dist/types/src/operations/definitions.d.ts +45 -0
- package/dist/types/src/operations/definitions.d.ts.map +1 -0
- package/dist/types/src/operations/index.d.ts +5 -0
- package/dist/types/src/operations/index.d.ts.map +1 -0
- package/dist/types/src/operations/services/google-credentials.d.ts +35 -0
- package/dist/types/src/operations/services/google-credentials.d.ts.map +1 -0
- package/dist/types/src/operations/services/index.d.ts +2 -0
- package/dist/types/src/operations/services/index.d.ts.map +1 -0
- package/dist/types/src/operations/sync.d.ts +5 -0
- package/dist/types/src/operations/sync.d.ts.map +1 -0
- package/dist/types/src/operations/sync.test.d.ts +2 -0
- package/dist/types/src/operations/sync.test.d.ts.map +1 -0
- package/dist/types/src/operations/transcript.d.ts +12 -0
- package/dist/types/src/operations/transcript.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +49 -0
- package/dist/types/src/translations.d.ts.map +1 -0
- package/dist/types/src/types/Channel.d.ts +54 -0
- package/dist/types/src/types/Channel.d.ts.map +1 -0
- package/dist/types/src/types/Video.d.ts +41 -0
- package/dist/types/src/types/Video.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +4 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/src/types/types.d.ts +5 -0
- package/dist/types/src/types/types.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +113 -0
- package/src/YouTubePlugin.tsx +66 -0
- package/src/blueprints/index.ts +7 -0
- package/src/blueprints/youtube.ts +52 -0
- package/src/capabilities/app-graph-builder/app-graph-builder.ts +148 -0
- package/src/capabilities/app-graph-builder/index.ts +7 -0
- package/src/capabilities/blueprint-definition/blueprint-definition.ts +17 -0
- package/src/capabilities/blueprint-definition/index.ts +7 -0
- package/src/capabilities/index.ts +7 -0
- package/src/capabilities/react-surface/index.ts +7 -0
- package/src/capabilities/react-surface/react-surface.tsx +54 -0
- package/src/containers/ChannelArticle/ChannelArticle.tsx +115 -0
- package/src/containers/ChannelArticle/index.ts +7 -0
- package/src/containers/ChannelSettings/ChannelSettings.tsx +34 -0
- package/src/containers/ChannelSettings/index.ts +7 -0
- package/src/containers/VideoArticle/VideoArticle.tsx +109 -0
- package/src/containers/VideoArticle/index.ts +7 -0
- package/src/containers/VideoCard/VideoCard.tsx +86 -0
- package/src/containers/VideoCard/index.ts +7 -0
- package/src/containers/index.ts +24 -0
- package/src/index.ts +8 -0
- package/src/meta.ts +19 -0
- package/src/operations/apis/index.ts +5 -0
- package/src/operations/apis/youtube/api.ts +149 -0
- package/src/operations/apis/youtube/index.ts +6 -0
- package/src/operations/apis/youtube/types.ts +254 -0
- package/src/operations/clear-synced-videos.ts +50 -0
- package/src/operations/definitions.ts +62 -0
- package/src/operations/index.ts +13 -0
- package/src/operations/services/google-credentials.ts +81 -0
- package/src/operations/services/index.ts +5 -0
- package/src/operations/sync.test.ts +114 -0
- package/src/operations/sync.ts +309 -0
- package/src/operations/transcript.ts +47 -0
- package/src/translations.ts +59 -0
- package/src/types/Channel.ts +80 -0
- package/src/types/Video.ts +67 -0
- package/src/types/index.ts +8 -0
- package/src/types/types.ts +10 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
__export
|
|
4
|
+
} from "./chunk-HSLMI22Q.mjs";
|
|
5
|
+
|
|
6
|
+
// src/types/types.ts
|
|
7
|
+
var YouTubeOperation = {};
|
|
8
|
+
|
|
9
|
+
// src/types/Channel.ts
|
|
10
|
+
var Channel_exports = {};
|
|
11
|
+
__export(Channel_exports, {
|
|
12
|
+
CreateYouTubeChannelSchema: () => CreateYouTubeChannelSchema,
|
|
13
|
+
YouTubeChannel: () => YouTubeChannel,
|
|
14
|
+
instanceOf: () => instanceOf,
|
|
15
|
+
make: () => make
|
|
16
|
+
});
|
|
17
|
+
import * as Schema from "effect/Schema";
|
|
18
|
+
import { Annotation, Feed, Obj, Ref, Type } from "@dxos/echo";
|
|
19
|
+
import { FormInputAnnotation } from "@dxos/echo/internal";
|
|
20
|
+
import { FeedAnnotation } from "@dxos/schema";
|
|
21
|
+
import { AccessToken } from "@dxos/types";
|
|
22
|
+
var YouTubeChannel = Schema.Struct({
|
|
23
|
+
/** Display name for the channel. */
|
|
24
|
+
name: Schema.String.pipe(Schema.optional),
|
|
25
|
+
/** YouTube channel ID (e.g., UC...). */
|
|
26
|
+
channelId: Schema.String.pipe(Schema.optional),
|
|
27
|
+
/** YouTube channel URL or handle. */
|
|
28
|
+
channelUrl: Schema.String.pipe(Schema.optional),
|
|
29
|
+
/** Feed containing YouTubeVideo objects. */
|
|
30
|
+
feed: Ref.Ref(Feed.Feed).pipe(FormInputAnnotation.set(false)),
|
|
31
|
+
/** Last sync timestamp. */
|
|
32
|
+
lastSyncedAt: Schema.String.pipe(FormInputAnnotation.set(false), Schema.optional),
|
|
33
|
+
/** Google API credentials for fetching channel data. */
|
|
34
|
+
accessToken: Schema.optional(Ref.Ref(AccessToken.AccessToken).annotations({
|
|
35
|
+
title: "Account",
|
|
36
|
+
description: "Google account credentials for syncing this YouTube channel."
|
|
37
|
+
}))
|
|
38
|
+
}).pipe(Type.object({
|
|
39
|
+
typename: "org.dxos.type.youtube-channel",
|
|
40
|
+
version: "0.1.0"
|
|
41
|
+
}), Annotation.IconAnnotation.set({
|
|
42
|
+
icon: "ph--youtube-logo--regular",
|
|
43
|
+
hue: "red"
|
|
44
|
+
}), FeedAnnotation.set(true));
|
|
45
|
+
var instanceOf = (value) => Obj.instanceOf(YouTubeChannel, value);
|
|
46
|
+
var CreateYouTubeChannelSchema = Schema.Struct({
|
|
47
|
+
name: Schema.optional(Schema.String.annotations({
|
|
48
|
+
title: "Name"
|
|
49
|
+
})),
|
|
50
|
+
channelUrl: Schema.optional(Schema.String.annotations({
|
|
51
|
+
title: "Channel URL",
|
|
52
|
+
description: "YouTube channel URL, handle (e.g., @channelname), or channel ID."
|
|
53
|
+
})),
|
|
54
|
+
accessToken: Schema.optional(Ref.Ref(AccessToken.AccessToken).annotations({
|
|
55
|
+
title: "Account",
|
|
56
|
+
description: "Google account credentials for syncing this YouTube channel."
|
|
57
|
+
}))
|
|
58
|
+
});
|
|
59
|
+
var make = (props = {}) => {
|
|
60
|
+
const feed = Feed.make();
|
|
61
|
+
const channel = Obj.make(YouTubeChannel, {
|
|
62
|
+
feed: Ref.make(feed),
|
|
63
|
+
...props
|
|
64
|
+
});
|
|
65
|
+
Obj.setParent(feed, channel);
|
|
66
|
+
return channel;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export {
|
|
70
|
+
YouTubeOperation,
|
|
71
|
+
Channel_exports
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=chunk-6BUJ2DQX.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/types/types.ts", "../../../src/types/Channel.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\n/**\n * YouTube plugin operations (placeholder for future expansion).\n */\nexport const YouTubeOperation = {\n // Operations will be defined here when needed.\n} as const;\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\nimport { Annotation, Feed, Obj, Ref, Type } from '@dxos/echo';\nimport { FormInputAnnotation } from '@dxos/echo/internal';\nimport { FeedAnnotation } from '@dxos/schema';\nimport { AccessToken } from '@dxos/types';\n\n// @import-as-namespace\n\n/**\n * YouTubeChannel schema representing a YouTube channel to sync videos from.\n */\nexport const YouTubeChannel = Schema.Struct({\n /** Display name for the channel. */\n name: Schema.String.pipe(Schema.optional),\n /** YouTube channel ID (e.g., UC...). */\n channelId: Schema.String.pipe(Schema.optional),\n /** YouTube channel URL or handle. */\n channelUrl: Schema.String.pipe(Schema.optional),\n /** Feed containing YouTubeVideo objects. */\n feed: Ref.Ref(Feed.Feed).pipe(FormInputAnnotation.set(false)),\n /** Last sync timestamp. */\n lastSyncedAt: Schema.String.pipe(FormInputAnnotation.set(false), Schema.optional),\n /** Google API credentials for fetching channel data. */\n accessToken: Schema.optional(\n Ref.Ref(AccessToken.AccessToken).annotations({\n title: 'Account',\n description: 'Google account credentials for syncing this YouTube channel.',\n }),\n ),\n}).pipe(\n Type.object({\n typename: 'org.dxos.type.youtube-channel',\n version: '0.1.0',\n }),\n Annotation.IconAnnotation.set({\n icon: 'ph--youtube-logo--regular',\n hue: 'red',\n }),\n FeedAnnotation.set(true),\n);\n\nexport interface YouTubeChannel extends Schema.Schema.Type<typeof YouTubeChannel> {}\n\n/** Checks if a value is a YouTubeChannel object. */\nexport const instanceOf = (value: unknown): value is YouTubeChannel => Obj.instanceOf(YouTubeChannel, value);\n\nexport const CreateYouTubeChannelSchema = Schema.Struct({\n name: Schema.optional(Schema.String.annotations({ title: 'Name' })),\n channelUrl: Schema.optional(\n Schema.String.annotations({\n title: 'Channel URL',\n description: 'YouTube channel URL, handle (e.g., @channelname), or channel ID.',\n }),\n ),\n accessToken: Schema.optional(\n Ref.Ref(AccessToken.AccessToken).annotations({\n title: 'Account',\n description: 'Google account credentials for syncing this YouTube channel.',\n }),\n ),\n});\nexport interface CreateYouTubeChannelSchema extends Schema.Schema.Type<typeof CreateYouTubeChannelSchema> {}\n\ntype YouTubeChannelProps = Omit<Obj.MakeProps<typeof YouTubeChannel>, 'feed' | 'lastSyncedAt'>;\n\n/** Creates a YouTubeChannel object with a backing feed. */\nexport const make = (props: YouTubeChannelProps = {}) => {\n const feed = Feed.make();\n const channel = Obj.make(YouTubeChannel, {\n feed: Ref.make(feed),\n ...props,\n });\n Obj.setParent(feed, channel);\n return channel;\n};\n"],
|
|
5
|
+
"mappings": ";;;;;;AAOO,IAAMA,mBAAmB,CAEhC;;;ACTA;;;;;;;AAIA,YAAYC,YAAY;AAExB,SAASC,YAAYC,MAAMC,KAAKC,KAAKC,YAAY;AACjD,SAASC,2BAA2B;AACpC,SAASC,sBAAsB;AAC/B,SAASC,mBAAmB;AAOrB,IAAMC,iBAAwBC,cAAO;;EAE1CC,MAAaC,cAAOC,KAAYC,eAAQ;;EAExCC,WAAkBH,cAAOC,KAAYC,eAAQ;;EAE7CE,YAAmBJ,cAAOC,KAAYC,eAAQ;;EAE9CG,MAAMC,IAAIA,IAAIC,KAAKA,IAAI,EAAEN,KAAKO,oBAAoBC,IAAI,KAAA,CAAA;;EAEtDC,cAAqBV,cAAOC,KAAKO,oBAAoBC,IAAI,KAAA,GAAeP,eAAQ;;EAEhFS,aAAoBT,gBAClBI,IAAIA,IAAIM,YAAYA,WAAW,EAAEC,YAAY;IAC3CC,OAAO;IACPC,aAAa;EACf,CAAA,CAAA;AAEJ,CAAA,EAAGd,KACDe,KAAKC,OAAO;EACVC,UAAU;EACVC,SAAS;AACX,CAAA,GACAC,WAAWC,eAAeZ,IAAI;EAC5Ba,MAAM;EACNC,KAAK;AACP,CAAA,GACAC,eAAef,IAAI,IAAA,CAAA;AAMd,IAAMgB,aAAa,CAACC,UAA4CC,IAAIF,WAAW5B,gBAAgB6B,KAAAA;AAE/F,IAAME,6BAAoC9B,cAAO;EACtDC,MAAaG,gBAAgBF,cAAOa,YAAY;IAAEC,OAAO;EAAO,CAAA,CAAA;EAChEV,YAAmBF,gBACVF,cAAOa,YAAY;IACxBC,OAAO;IACPC,aAAa;EACf,CAAA,CAAA;EAEFJ,aAAoBT,gBAClBI,IAAIA,IAAIM,YAAYA,WAAW,EAAEC,YAAY;IAC3CC,OAAO;IACPC,aAAa;EACf,CAAA,CAAA;AAEJ,CAAA;AAMO,IAAMc,OAAO,CAACC,QAA6B,CAAC,MAAC;AAClD,QAAMzB,OAAOE,KAAKsB,KAAI;AACtB,QAAME,UAAUJ,IAAIE,KAAKhC,gBAAgB;IACvCQ,MAAMC,IAAIuB,KAAKxB,IAAAA;IACf,GAAGyB;EACL,CAAA;AACAH,MAAIK,UAAU3B,MAAM0B,OAAAA;AACpB,SAAOA;AACT;",
|
|
6
|
+
"names": ["YouTubeOperation", "Schema", "Annotation", "Feed", "Obj", "Ref", "Type", "FormInputAnnotation", "FeedAnnotation", "AccessToken", "YouTubeChannel", "Struct", "name", "String", "pipe", "optional", "channelId", "channelUrl", "feed", "Ref", "Feed", "FormInputAnnotation", "set", "lastSyncedAt", "accessToken", "AccessToken", "annotations", "title", "description", "Type", "object", "typename", "version", "Annotation", "IconAnnotation", "icon", "hue", "FeedAnnotation", "instanceOf", "value", "Obj", "CreateYouTubeChannelSchema", "make", "props", "channel", "setParent"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// src/meta.ts
|
|
4
|
+
import { trim } from "@dxos/util";
|
|
5
|
+
var meta = {
|
|
6
|
+
id: "org.dxos.plugin.youtube",
|
|
7
|
+
name: "YouTube",
|
|
8
|
+
description: trim`
|
|
9
|
+
YouTube channel subscription and video feed management.
|
|
10
|
+
Sync videos from channels and access transcripts for analysis.
|
|
11
|
+
`,
|
|
12
|
+
icon: "ph--youtube-logo--regular",
|
|
13
|
+
iconHue: "red",
|
|
14
|
+
source: "https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-youtube",
|
|
15
|
+
tags: [
|
|
16
|
+
"labs"
|
|
17
|
+
]
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export {
|
|
21
|
+
meta
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=chunk-CX6MV3QM.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/meta.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { type Plugin } from '@dxos/app-framework';\nimport { trim } from '@dxos/util';\n\nexport const meta: Plugin.Meta = {\n id: 'org.dxos.plugin.youtube',\n name: 'YouTube',\n description: trim`\n YouTube channel subscription and video feed management.\n Sync videos from channels and access transcripts for analysis.\n `,\n icon: 'ph--youtube-logo--regular',\n iconHue: 'red',\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-youtube',\n tags: ['labs'],\n};\n"],
|
|
5
|
+
"mappings": ";;;AAKA,SAASA,YAAY;AAEd,IAAMC,OAAoB;EAC/BC,IAAI;EACJC,MAAM;EACNC,aAAaC;;;;EAIbC,MAAM;EACNC,SAAS;EACTC,QAAQ;EACRC,MAAM;IAAC;;AACT;",
|
|
6
|
+
"names": ["trim", "meta", "id", "name", "description", "trim", "icon", "iconHue", "source", "tags"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
__export
|
|
4
|
+
} from "./chunk-HSLMI22Q.mjs";
|
|
5
|
+
|
|
6
|
+
// src/types/Video.ts
|
|
7
|
+
var Video_exports = {};
|
|
8
|
+
__export(Video_exports, {
|
|
9
|
+
TranscriptSegment: () => TranscriptSegment,
|
|
10
|
+
YouTubeVideo: () => YouTubeVideo,
|
|
11
|
+
instanceOf: () => instanceOf
|
|
12
|
+
});
|
|
13
|
+
import * as Schema from "effect/Schema";
|
|
14
|
+
import { Annotation, Obj, Type } from "@dxos/echo";
|
|
15
|
+
var TranscriptSegment = Schema.Struct({
|
|
16
|
+
/** Transcript text. */
|
|
17
|
+
text: Schema.String,
|
|
18
|
+
/** Start time in seconds. */
|
|
19
|
+
offset: Schema.Number,
|
|
20
|
+
/** Duration in seconds. */
|
|
21
|
+
duration: Schema.Number
|
|
22
|
+
});
|
|
23
|
+
var YouTubeVideo = Schema.Struct({
|
|
24
|
+
/** Video title. */
|
|
25
|
+
title: Schema.String,
|
|
26
|
+
/** YouTube video ID. */
|
|
27
|
+
videoId: Schema.String,
|
|
28
|
+
/** Video description. */
|
|
29
|
+
description: Schema.String.pipe(Schema.optional),
|
|
30
|
+
/** Video URL. */
|
|
31
|
+
url: Schema.String,
|
|
32
|
+
/** Thumbnail URL. */
|
|
33
|
+
thumbnailUrl: Schema.String.pipe(Schema.optional),
|
|
34
|
+
/** Channel name. */
|
|
35
|
+
channelTitle: Schema.String.pipe(Schema.optional),
|
|
36
|
+
/** Published date as ISO string. */
|
|
37
|
+
publishedAt: Schema.String,
|
|
38
|
+
/** Video duration in ISO 8601 format (e.g., PT1H30M15S). */
|
|
39
|
+
duration: Schema.String.pipe(Schema.optional),
|
|
40
|
+
/** View count. */
|
|
41
|
+
viewCount: Schema.Number.pipe(Schema.optional),
|
|
42
|
+
/** Like count. */
|
|
43
|
+
likeCount: Schema.Number.pipe(Schema.optional),
|
|
44
|
+
/** Full transcript text. */
|
|
45
|
+
transcript: Schema.String.pipe(Schema.optional),
|
|
46
|
+
/** Transcript segments with timestamps. */
|
|
47
|
+
transcriptSegments: Schema.Array(TranscriptSegment).pipe(Schema.optional),
|
|
48
|
+
/** True when transcript text was successfully loaded; false when disabled or none available. */
|
|
49
|
+
transcriptFetched: Schema.Boolean.pipe(Schema.optional)
|
|
50
|
+
}).pipe(Type.object({
|
|
51
|
+
typename: "org.dxos.type.youtube-video",
|
|
52
|
+
version: "0.1.0"
|
|
53
|
+
}), Annotation.IconAnnotation.set({
|
|
54
|
+
icon: "ph--play--regular",
|
|
55
|
+
hue: "red"
|
|
56
|
+
}));
|
|
57
|
+
var instanceOf = (value) => Obj.instanceOf(YouTubeVideo, value);
|
|
58
|
+
|
|
59
|
+
export {
|
|
60
|
+
YouTubeVideo,
|
|
61
|
+
Video_exports
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=chunk-CZSLL3XQ.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/types/Video.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\nimport { Annotation, Obj, Type } from '@dxos/echo';\n\n/**\n * Transcript segment from a YouTube video.\n */\nexport const TranscriptSegment = Schema.Struct({\n /** Transcript text. */\n text: Schema.String,\n /** Start time in seconds. */\n offset: Schema.Number,\n /** Duration in seconds. */\n duration: Schema.Number,\n});\n\nexport type TranscriptSegment = Schema.Schema.Type<typeof TranscriptSegment>;\n\n/**\n * YouTubeVideo schema representing a video from a YouTube channel.\n */\nexport const YouTubeVideo = Schema.Struct({\n /** Video title. */\n title: Schema.String,\n /** YouTube video ID. */\n videoId: Schema.String,\n /** Video description. */\n description: Schema.String.pipe(Schema.optional),\n /** Video URL. */\n url: Schema.String,\n /** Thumbnail URL. */\n thumbnailUrl: Schema.String.pipe(Schema.optional),\n /** Channel name. */\n channelTitle: Schema.String.pipe(Schema.optional),\n /** Published date as ISO string. */\n publishedAt: Schema.String,\n /** Video duration in ISO 8601 format (e.g., PT1H30M15S). */\n duration: Schema.String.pipe(Schema.optional),\n /** View count. */\n viewCount: Schema.Number.pipe(Schema.optional),\n /** Like count. */\n likeCount: Schema.Number.pipe(Schema.optional),\n /** Full transcript text. */\n transcript: Schema.String.pipe(Schema.optional),\n /** Transcript segments with timestamps. */\n transcriptSegments: Schema.Array(TranscriptSegment).pipe(Schema.optional),\n /** True when transcript text was successfully loaded; false when disabled or none available. */\n transcriptFetched: Schema.Boolean.pipe(Schema.optional),\n}).pipe(\n Type.object({\n typename: 'org.dxos.type.youtube-video',\n version: '0.1.0',\n }),\n Annotation.IconAnnotation.set({\n icon: 'ph--play--regular',\n hue: 'red',\n }),\n);\n\nexport interface YouTubeVideo extends Schema.Schema.Type<typeof YouTubeVideo> {}\n\n/** Checks if a value is a YouTubeVideo object. */\nexport const instanceOf = (value: unknown): value is YouTubeVideo => Obj.instanceOf(YouTubeVideo, value);\n"],
|
|
5
|
+
"mappings": ";;;;;;AAAA;;;;;;AAIA,YAAYA,YAAY;AAExB,SAASC,YAAYC,KAAKC,YAAY;AAK/B,IAAMC,oBAA2BC,cAAO;;EAE7CC,MAAaC;;EAEbC,QAAeC;;EAEfC,UAAiBD;AACnB,CAAA;AAOO,IAAME,eAAsBN,cAAO;;EAExCO,OAAcL;;EAEdM,SAAgBN;;EAEhBO,aAAoBP,cAAOQ,KAAYC,eAAQ;;EAE/CC,KAAYV;;EAEZW,cAAqBX,cAAOQ,KAAYC,eAAQ;;EAEhDG,cAAqBZ,cAAOQ,KAAYC,eAAQ;;EAEhDI,aAAoBb;;EAEpBG,UAAiBH,cAAOQ,KAAYC,eAAQ;;EAE5CK,WAAkBZ,cAAOM,KAAYC,eAAQ;;EAE7CM,WAAkBb,cAAOM,KAAYC,eAAQ;;EAE7CO,YAAmBhB,cAAOQ,KAAYC,eAAQ;;EAE9CQ,oBAA2BC,aAAMrB,iBAAAA,EAAmBW,KAAYC,eAAQ;;EAExEU,mBAA0BC,eAAQZ,KAAYC,eAAQ;AACxD,CAAA,EAAGD,KACDa,KAAKC,OAAO;EACVC,UAAU;EACVC,SAAS;AACX,CAAA,GACAC,WAAWC,eAAeC,IAAI;EAC5BC,MAAM;EACNC,KAAK;AACP,CAAA,CAAA;AAMK,IAAMC,aAAa,CAACC,UAA0CC,IAAIF,WAAW1B,cAAc2B,KAAAA;",
|
|
6
|
+
"names": ["Schema", "Annotation", "Obj", "Type", "TranscriptSegment", "Struct", "text", "String", "offset", "Number", "duration", "YouTubeVideo", "title", "videoId", "description", "pipe", "optional", "url", "thumbnailUrl", "channelTitle", "publishedAt", "viewCount", "likeCount", "transcript", "transcriptSegments", "Array", "transcriptFetched", "Boolean", "Type", "object", "typename", "version", "Annotation", "IconAnnotation", "set", "icon", "hue", "instanceOf", "value", "Obj"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __export = (target, all) => {
|
|
4
|
+
for (var name in all)
|
|
5
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
__export
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=chunk-HSLMI22Q.mjs.map
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
__export
|
|
4
|
+
} from "./chunk-HSLMI22Q.mjs";
|
|
5
|
+
|
|
6
|
+
// src/operations/services/google-credentials.ts
|
|
7
|
+
import * as Context from "effect/Context";
|
|
8
|
+
import * as Effect from "effect/Effect";
|
|
9
|
+
import * as Layer from "effect/Layer";
|
|
10
|
+
import { Database } from "@dxos/echo";
|
|
11
|
+
import { CredentialsService } from "@dxos/functions";
|
|
12
|
+
import { log } from "@dxos/log";
|
|
13
|
+
var __dxlog_file = "/Users/mykola/dev/dxos/packages/plugins/plugin-youtube/src/operations/services/google-credentials.ts";
|
|
14
|
+
var makeService = (cachedToken) => ({
|
|
15
|
+
get: () => cachedToken ? Effect.succeed(cachedToken) : Effect.map(CredentialsService.getCredential({
|
|
16
|
+
service: "google.com"
|
|
17
|
+
}), (credential) => credential.apiKey)
|
|
18
|
+
});
|
|
19
|
+
var loadAccessToken = (accessTokenRef, label) => Effect.gen(function* () {
|
|
20
|
+
if (accessTokenRef) {
|
|
21
|
+
const accessToken = yield* Database.load(accessTokenRef);
|
|
22
|
+
if (accessToken?.token) {
|
|
23
|
+
log(`using ${label}-specific access token`, {
|
|
24
|
+
note: accessToken.note
|
|
25
|
+
}, {
|
|
26
|
+
F: __dxlog_file,
|
|
27
|
+
L: 35,
|
|
28
|
+
S: this,
|
|
29
|
+
C: (f, a) => f(...a)
|
|
30
|
+
});
|
|
31
|
+
return accessToken.token;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return void 0;
|
|
35
|
+
});
|
|
36
|
+
var GoogleCredentials = class _GoogleCredentials extends Context.Tag("GoogleCredentials")() {
|
|
37
|
+
/**
|
|
38
|
+
* Creates a credentials layer from a channel.
|
|
39
|
+
* Pre-loads the access token during layer construction.
|
|
40
|
+
*/
|
|
41
|
+
static fromChannel = (channel) => Layer.effect(_GoogleCredentials, Effect.map(loadAccessToken(channel.accessToken, "channel"), makeService));
|
|
42
|
+
/**
|
|
43
|
+
* Creates a credentials layer from a channel ref.
|
|
44
|
+
* Loads the channel and pre-loads the access token during layer construction.
|
|
45
|
+
*/
|
|
46
|
+
static fromChannelRef = (channelRef) => Layer.effect(_GoogleCredentials, Effect.flatMap(Database.load(channelRef), (channel) => Effect.map(loadAccessToken(channel.accessToken, "channel"), makeService)));
|
|
47
|
+
/**
|
|
48
|
+
* Default layer that uses database credentials.
|
|
49
|
+
* Use this for operations that don't have an associated channel.
|
|
50
|
+
*/
|
|
51
|
+
static default = Layer.succeed(_GoogleCredentials, makeService(void 0));
|
|
52
|
+
/** Convenience accessor - returns the Google API token. */
|
|
53
|
+
static get = () => Effect.flatMap(_GoogleCredentials, (service) => service.get());
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// src/operations/apis/youtube/index.ts
|
|
57
|
+
var youtube_exports = {};
|
|
58
|
+
__export(youtube_exports, {
|
|
59
|
+
CaptionResource: () => CaptionResource,
|
|
60
|
+
CaptionsListResponse: () => CaptionsListResponse,
|
|
61
|
+
ChannelItem: () => ChannelItem,
|
|
62
|
+
ChannelSnippet: () => ChannelSnippet,
|
|
63
|
+
ChannelsResponse: () => ChannelsResponse,
|
|
64
|
+
ErrorResponse: () => ErrorResponse,
|
|
65
|
+
PlaylistItem: () => PlaylistItem,
|
|
66
|
+
PlaylistItemsResponse: () => PlaylistItemsResponse,
|
|
67
|
+
SearchItem: () => SearchItem,
|
|
68
|
+
SearchResponse: () => SearchResponse,
|
|
69
|
+
VideoContentDetails: () => VideoContentDetails,
|
|
70
|
+
VideoItem: () => VideoItem,
|
|
71
|
+
VideoSnippet: () => VideoSnippet,
|
|
72
|
+
VideoStatistics: () => VideoStatistics,
|
|
73
|
+
VideosResponse: () => VideosResponse,
|
|
74
|
+
YouTubeError: () => YouTubeError,
|
|
75
|
+
getChannel: () => getChannel,
|
|
76
|
+
getChannelByHandle: () => getChannelByHandle,
|
|
77
|
+
getVideoDetails: () => getVideoDetails,
|
|
78
|
+
listPlaylistItems: () => listPlaylistItems,
|
|
79
|
+
searchChannels: () => searchChannels
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// src/operations/apis/youtube/api.ts
|
|
83
|
+
import * as HttpClient from "@effect/platform/HttpClient";
|
|
84
|
+
import * as HttpClientRequest from "@effect/platform/HttpClientRequest";
|
|
85
|
+
import * as Effect2 from "effect/Effect";
|
|
86
|
+
import * as Schedule from "effect/Schedule";
|
|
87
|
+
import * as Schema2 from "effect/Schema";
|
|
88
|
+
import { withAuthorization } from "@dxos/functions";
|
|
89
|
+
import { log as log2 } from "@dxos/log";
|
|
90
|
+
|
|
91
|
+
// src/operations/apis/youtube/types.ts
|
|
92
|
+
import * as Schema from "effect/Schema";
|
|
93
|
+
var YouTubeError = class _YouTubeError extends Schema.TaggedError()("YouTubeError", {
|
|
94
|
+
code: Schema.Number,
|
|
95
|
+
message: Schema.String,
|
|
96
|
+
status: Schema.optional(Schema.String)
|
|
97
|
+
}) {
|
|
98
|
+
static fromErrorResponse(response) {
|
|
99
|
+
return new _YouTubeError({
|
|
100
|
+
code: response.error.code,
|
|
101
|
+
message: response.error.message,
|
|
102
|
+
status: response.error.status
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
var ErrorResponse = Schema.Struct({
|
|
107
|
+
error: Schema.Struct({
|
|
108
|
+
code: Schema.Number,
|
|
109
|
+
message: Schema.String,
|
|
110
|
+
status: Schema.optional(Schema.String)
|
|
111
|
+
})
|
|
112
|
+
});
|
|
113
|
+
var ChannelSnippet = Schema.Struct({
|
|
114
|
+
title: Schema.String,
|
|
115
|
+
description: Schema.optional(Schema.String),
|
|
116
|
+
customUrl: Schema.optional(Schema.String),
|
|
117
|
+
publishedAt: Schema.optional(Schema.String),
|
|
118
|
+
thumbnails: Schema.optional(Schema.Struct({
|
|
119
|
+
default: Schema.optional(Schema.Struct({
|
|
120
|
+
url: Schema.String
|
|
121
|
+
})),
|
|
122
|
+
medium: Schema.optional(Schema.Struct({
|
|
123
|
+
url: Schema.String
|
|
124
|
+
})),
|
|
125
|
+
high: Schema.optional(Schema.Struct({
|
|
126
|
+
url: Schema.String
|
|
127
|
+
}))
|
|
128
|
+
}))
|
|
129
|
+
});
|
|
130
|
+
var ChannelItem = Schema.Struct({
|
|
131
|
+
kind: Schema.String,
|
|
132
|
+
etag: Schema.String,
|
|
133
|
+
id: Schema.String,
|
|
134
|
+
snippet: Schema.optional(ChannelSnippet),
|
|
135
|
+
contentDetails: Schema.optional(Schema.Struct({
|
|
136
|
+
relatedPlaylists: Schema.optional(Schema.Struct({
|
|
137
|
+
uploads: Schema.optional(Schema.String)
|
|
138
|
+
}))
|
|
139
|
+
}))
|
|
140
|
+
});
|
|
141
|
+
var ChannelsResponse = Schema.Struct({
|
|
142
|
+
kind: Schema.String,
|
|
143
|
+
etag: Schema.String,
|
|
144
|
+
pageInfo: Schema.optional(Schema.Struct({
|
|
145
|
+
totalResults: Schema.Number,
|
|
146
|
+
resultsPerPage: Schema.Number
|
|
147
|
+
})),
|
|
148
|
+
items: Schema.Array(ChannelItem)
|
|
149
|
+
});
|
|
150
|
+
var VideoSnippet = Schema.Struct({
|
|
151
|
+
publishedAt: Schema.String,
|
|
152
|
+
channelId: Schema.optional(Schema.String),
|
|
153
|
+
title: Schema.String,
|
|
154
|
+
description: Schema.optional(Schema.String),
|
|
155
|
+
thumbnails: Schema.optional(Schema.Struct({
|
|
156
|
+
default: Schema.optional(Schema.Struct({
|
|
157
|
+
url: Schema.String
|
|
158
|
+
})),
|
|
159
|
+
medium: Schema.optional(Schema.Struct({
|
|
160
|
+
url: Schema.String
|
|
161
|
+
})),
|
|
162
|
+
high: Schema.optional(Schema.Struct({
|
|
163
|
+
url: Schema.String
|
|
164
|
+
})),
|
|
165
|
+
standard: Schema.optional(Schema.Struct({
|
|
166
|
+
url: Schema.String
|
|
167
|
+
})),
|
|
168
|
+
maxres: Schema.optional(Schema.Struct({
|
|
169
|
+
url: Schema.String
|
|
170
|
+
}))
|
|
171
|
+
})),
|
|
172
|
+
channelTitle: Schema.optional(Schema.String),
|
|
173
|
+
playlistId: Schema.optional(Schema.String),
|
|
174
|
+
position: Schema.optional(Schema.Number),
|
|
175
|
+
resourceId: Schema.optional(Schema.Struct({
|
|
176
|
+
kind: Schema.String,
|
|
177
|
+
videoId: Schema.String
|
|
178
|
+
}))
|
|
179
|
+
});
|
|
180
|
+
var VideoContentDetails = Schema.Struct({
|
|
181
|
+
videoId: Schema.optional(Schema.String),
|
|
182
|
+
videoPublishedAt: Schema.optional(Schema.String),
|
|
183
|
+
duration: Schema.optional(Schema.String)
|
|
184
|
+
});
|
|
185
|
+
var VideoStatistics = Schema.Struct({
|
|
186
|
+
viewCount: Schema.optional(Schema.String),
|
|
187
|
+
likeCount: Schema.optional(Schema.String),
|
|
188
|
+
commentCount: Schema.optional(Schema.String)
|
|
189
|
+
});
|
|
190
|
+
var VideoItem = Schema.Struct({
|
|
191
|
+
kind: Schema.String,
|
|
192
|
+
etag: Schema.String,
|
|
193
|
+
id: Schema.String,
|
|
194
|
+
snippet: Schema.optional(VideoSnippet),
|
|
195
|
+
contentDetails: Schema.optional(VideoContentDetails),
|
|
196
|
+
statistics: Schema.optional(VideoStatistics)
|
|
197
|
+
});
|
|
198
|
+
var VideosResponse = Schema.Struct({
|
|
199
|
+
kind: Schema.String,
|
|
200
|
+
etag: Schema.String,
|
|
201
|
+
nextPageToken: Schema.optional(Schema.String),
|
|
202
|
+
prevPageToken: Schema.optional(Schema.String),
|
|
203
|
+
pageInfo: Schema.optional(Schema.Struct({
|
|
204
|
+
totalResults: Schema.Number,
|
|
205
|
+
resultsPerPage: Schema.Number
|
|
206
|
+
})),
|
|
207
|
+
items: Schema.Array(VideoItem)
|
|
208
|
+
});
|
|
209
|
+
var PlaylistItem = Schema.Struct({
|
|
210
|
+
kind: Schema.String,
|
|
211
|
+
etag: Schema.String,
|
|
212
|
+
id: Schema.String,
|
|
213
|
+
snippet: Schema.optional(VideoSnippet),
|
|
214
|
+
contentDetails: Schema.optional(VideoContentDetails)
|
|
215
|
+
});
|
|
216
|
+
var PlaylistItemsResponse = Schema.Struct({
|
|
217
|
+
kind: Schema.String,
|
|
218
|
+
etag: Schema.String,
|
|
219
|
+
nextPageToken: Schema.optional(Schema.String),
|
|
220
|
+
prevPageToken: Schema.optional(Schema.String),
|
|
221
|
+
pageInfo: Schema.optional(Schema.Struct({
|
|
222
|
+
totalResults: Schema.Number,
|
|
223
|
+
resultsPerPage: Schema.Number
|
|
224
|
+
})),
|
|
225
|
+
items: Schema.Array(PlaylistItem)
|
|
226
|
+
});
|
|
227
|
+
var SearchItem = Schema.Struct({
|
|
228
|
+
kind: Schema.String,
|
|
229
|
+
etag: Schema.String,
|
|
230
|
+
id: Schema.Struct({
|
|
231
|
+
kind: Schema.String,
|
|
232
|
+
videoId: Schema.optional(Schema.String),
|
|
233
|
+
channelId: Schema.optional(Schema.String),
|
|
234
|
+
playlistId: Schema.optional(Schema.String)
|
|
235
|
+
}),
|
|
236
|
+
snippet: Schema.optional(VideoSnippet)
|
|
237
|
+
});
|
|
238
|
+
var SearchResponse = Schema.Struct({
|
|
239
|
+
kind: Schema.String,
|
|
240
|
+
etag: Schema.String,
|
|
241
|
+
nextPageToken: Schema.optional(Schema.String),
|
|
242
|
+
prevPageToken: Schema.optional(Schema.String),
|
|
243
|
+
pageInfo: Schema.optional(Schema.Struct({
|
|
244
|
+
totalResults: Schema.Number,
|
|
245
|
+
resultsPerPage: Schema.Number
|
|
246
|
+
})),
|
|
247
|
+
items: Schema.Array(SearchItem)
|
|
248
|
+
});
|
|
249
|
+
var CaptionResource = Schema.Struct({
|
|
250
|
+
id: Schema.String,
|
|
251
|
+
snippet: Schema.optional(Schema.Struct({
|
|
252
|
+
videoId: Schema.optional(Schema.String),
|
|
253
|
+
language: Schema.optional(Schema.String),
|
|
254
|
+
name: Schema.optional(Schema.String),
|
|
255
|
+
trackKind: Schema.optional(Schema.String)
|
|
256
|
+
}))
|
|
257
|
+
});
|
|
258
|
+
var CaptionsListResponse = Schema.Struct({
|
|
259
|
+
kind: Schema.String,
|
|
260
|
+
etag: Schema.String,
|
|
261
|
+
items: Schema.optional(Schema.Array(CaptionResource))
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
// src/operations/apis/youtube/api.ts
|
|
265
|
+
var __dxlog_file2 = "/Users/mykola/dev/dxos/packages/plugins/plugin-youtube/src/operations/apis/youtube/api.ts";
|
|
266
|
+
var API_URL = "https://www.googleapis.com/youtube/v3";
|
|
267
|
+
var createUrl = (parts, params) => {
|
|
268
|
+
const url = new URL(parts.filter(Boolean).join("/"));
|
|
269
|
+
if (params) {
|
|
270
|
+
Object.entries(params).filter(([_, value]) => value != null).forEach(([key, value]) => url.searchParams.set(key, String(value)));
|
|
271
|
+
}
|
|
272
|
+
return url;
|
|
273
|
+
};
|
|
274
|
+
var decodeAndHandleErrors = (schema) => (data) => Schema2.decodeUnknown(Schema2.Union(schema, ErrorResponse))(data).pipe(Effect2.flatMap((response) => {
|
|
275
|
+
if ("error" in response) {
|
|
276
|
+
return Effect2.fail(YouTubeError.fromErrorResponse(response));
|
|
277
|
+
} else {
|
|
278
|
+
return Effect2.succeed(response);
|
|
279
|
+
}
|
|
280
|
+
}));
|
|
281
|
+
var makeYouTubeApiRequest = Effect2.fn("makeYouTubeApiRequest")(function* (url) {
|
|
282
|
+
const token = yield* GoogleCredentials.get();
|
|
283
|
+
const httpClient = yield* HttpClient.HttpClient.pipe(Effect2.map(withAuthorization(token, "Bearer")));
|
|
284
|
+
const httpClientWithTracerDisabled = httpClient.pipe(HttpClient.withTracerDisabledWhen(() => true));
|
|
285
|
+
const request = HttpClientRequest.get(url);
|
|
286
|
+
const response = yield* request.pipe(HttpClientRequest.setHeader("accept", "application/json"), httpClientWithTracerDisabled.execute, Effect2.flatMap((res) => res.json), Effect2.timeout("10 seconds"), Effect2.retry(Schedule.exponential(1e3).pipe(Schedule.compose(Schedule.recurs(3)))), Effect2.scoped, Effect2.withSpan("YouTubeApiRequest"));
|
|
287
|
+
if (response.error) {
|
|
288
|
+
log2.catch(response.error, void 0, {
|
|
289
|
+
F: __dxlog_file2,
|
|
290
|
+
L: 81,
|
|
291
|
+
S: this,
|
|
292
|
+
C: (f, a) => f(...a)
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
return response;
|
|
296
|
+
});
|
|
297
|
+
var getChannel = Effect2.fn(function* (channelId) {
|
|
298
|
+
const url = createUrl([
|
|
299
|
+
API_URL,
|
|
300
|
+
"channels"
|
|
301
|
+
], {
|
|
302
|
+
part: "snippet,contentDetails",
|
|
303
|
+
id: channelId
|
|
304
|
+
}).toString();
|
|
305
|
+
return yield* makeYouTubeApiRequest(url).pipe(Effect2.flatMap(decodeAndHandleErrors(ChannelsResponse)));
|
|
306
|
+
});
|
|
307
|
+
var getChannelByHandle = Effect2.fn(function* (handle) {
|
|
308
|
+
const url = createUrl([
|
|
309
|
+
API_URL,
|
|
310
|
+
"channels"
|
|
311
|
+
], {
|
|
312
|
+
part: "snippet,contentDetails",
|
|
313
|
+
forHandle: handle.startsWith("@") ? handle.slice(1) : handle
|
|
314
|
+
}).toString();
|
|
315
|
+
return yield* makeYouTubeApiRequest(url).pipe(Effect2.flatMap(decodeAndHandleErrors(ChannelsResponse)));
|
|
316
|
+
});
|
|
317
|
+
var searchChannels = Effect2.fn(function* (query, maxResults = 10) {
|
|
318
|
+
const url = createUrl([
|
|
319
|
+
API_URL,
|
|
320
|
+
"search"
|
|
321
|
+
], {
|
|
322
|
+
part: "snippet",
|
|
323
|
+
type: "channel",
|
|
324
|
+
q: query,
|
|
325
|
+
maxResults
|
|
326
|
+
}).toString();
|
|
327
|
+
return yield* makeYouTubeApiRequest(url).pipe(Effect2.flatMap(decodeAndHandleErrors(SearchResponse)));
|
|
328
|
+
});
|
|
329
|
+
var listPlaylistItems = Effect2.fn(function* (playlistId, maxResults = 50, pageToken) {
|
|
330
|
+
const url = createUrl([
|
|
331
|
+
API_URL,
|
|
332
|
+
"playlistItems"
|
|
333
|
+
], {
|
|
334
|
+
part: "snippet,contentDetails",
|
|
335
|
+
playlistId,
|
|
336
|
+
maxResults,
|
|
337
|
+
pageToken
|
|
338
|
+
}).toString();
|
|
339
|
+
return yield* makeYouTubeApiRequest(url).pipe(Effect2.flatMap(decodeAndHandleErrors(PlaylistItemsResponse)));
|
|
340
|
+
});
|
|
341
|
+
var getVideoDetails = Effect2.fn(function* (videoIds) {
|
|
342
|
+
const url = createUrl([
|
|
343
|
+
API_URL,
|
|
344
|
+
"videos"
|
|
345
|
+
], {
|
|
346
|
+
part: "snippet,contentDetails,statistics",
|
|
347
|
+
id: videoIds.join(",")
|
|
348
|
+
}).toString();
|
|
349
|
+
return yield* makeYouTubeApiRequest(url).pipe(Effect2.flatMap(decodeAndHandleErrors(VideosResponse)));
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
export {
|
|
353
|
+
GoogleCredentials,
|
|
354
|
+
youtube_exports
|
|
355
|
+
};
|
|
356
|
+
//# sourceMappingURL=chunk-JM5SBBP5.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/operations/services/google-credentials.ts", "../../../src/operations/apis/youtube/index.ts", "../../../src/operations/apis/youtube/api.ts", "../../../src/operations/apis/youtube/types.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Context from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\n\nimport { Database, type Ref } from '@dxos/echo';\nimport { CredentialsService } from '@dxos/functions';\nimport { log } from '@dxos/log';\nimport { type AccessToken } from '@dxos/types';\n\nimport type * as Channel from '../../types/Channel';\n\n/**\n * Creates the service interface from a cached token.\n * Falls back to database credentials if no cached token is provided.\n */\nconst makeService = (cachedToken: string | undefined): Context.Tag.Service<GoogleCredentials> => ({\n get: () =>\n cachedToken\n ? Effect.succeed(cachedToken)\n : Effect.map(CredentialsService.getCredential({ service: 'google.com' }), (credential) => credential.apiKey!),\n});\n\n/**\n * Loads access token from a ref if available.\n */\nconst loadAccessToken = (accessTokenRef: Ref.Ref<AccessToken.AccessToken> | undefined, label: string) =>\n Effect.gen(function* () {\n if (accessTokenRef) {\n const accessToken = yield* Database.load(accessTokenRef);\n if (accessToken?.token) {\n log(`using ${label}-specific access token`, { note: accessToken.note });\n return accessToken.token;\n }\n }\n return undefined;\n });\n\n/**\n * Service for accessing Google API credentials.\n * Provides the Google API token either from an object's access token or falls back to database credentials.\n */\n// TODO(dmaretskyi): Remove this service.\nexport class GoogleCredentials extends Context.Tag('GoogleCredentials')<\n GoogleCredentials,\n {\n /** Returns the Google API token. */\n get: () => Effect.Effect<string, never, CredentialsService>;\n }\n>() {\n /**\n * Creates a credentials layer from a channel.\n * Pre-loads the access token during layer construction.\n */\n static fromChannel = (channel: Channel.YouTubeChannel) =>\n Layer.effect(GoogleCredentials, Effect.map(loadAccessToken(channel.accessToken, 'channel'), makeService));\n\n /**\n * Creates a credentials layer from a channel ref.\n * Loads the channel and pre-loads the access token during layer construction.\n */\n static fromChannelRef = (channelRef: Ref.Ref<Channel.YouTubeChannel>) =>\n Layer.effect(\n GoogleCredentials,\n Effect.flatMap(Database.load(channelRef), (channel) =>\n Effect.map(loadAccessToken(channel.accessToken, 'channel'), makeService),\n ),\n );\n\n /**\n * Default layer that uses database credentials.\n * Use this for operations that don't have an associated channel.\n */\n static default = Layer.succeed(GoogleCredentials, makeService(undefined));\n\n /** Convenience accessor - returns the Google API token. */\n static get = () => Effect.flatMap(GoogleCredentials, (service) => service.get());\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nexport * from './api';\nexport * from './types';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport * as HttpClient from '@effect/platform/HttpClient';\nimport * as HttpClientRequest from '@effect/platform/HttpClientRequest';\nimport * as Effect from 'effect/Effect';\nimport type * as ParseResult from 'effect/ParseResult';\nimport * as Schedule from 'effect/Schedule';\nimport * as Schema from 'effect/Schema';\n\nimport { withAuthorization } from '@dxos/functions';\nimport { log } from '@dxos/log';\n\nimport { GoogleCredentials } from '../../services/google-credentials';\n\nimport {\n ChannelsResponse,\n ErrorResponse,\n PlaylistItemsResponse,\n SearchResponse,\n VideosResponse,\n YouTubeError,\n} from './types';\n\nconst API_URL = 'https://www.googleapis.com/youtube/v3';\n\n/**\n * Creates a URL from path segments and query parameters.\n */\nconst createUrl = (parts: (string | undefined)[], params?: Record<string, unknown>): URL => {\n const url = new URL(parts.filter(Boolean).join('/'));\n if (params) {\n Object.entries(params)\n .filter(([_, value]) => value != null)\n .forEach(([key, value]) => url.searchParams.set(key, String(value)));\n }\n return url;\n};\n\n/**\n * Decode response and handle YouTube API errors.\n */\nconst decodeAndHandleErrors =\n <S extends Schema.Schema.Any>(schema: S) =>\n (\n data: unknown,\n ): Effect.Effect<Schema.Schema.Type<S>, YouTubeError | ParseResult.ParseError, Schema.Schema.Context<S>> =>\n Schema.decodeUnknown(Schema.Union(schema, ErrorResponse))(data).pipe(\n Effect.flatMap((response) => {\n if ('error' in response) {\n return Effect.fail(YouTubeError.fromErrorResponse(response));\n } else {\n return Effect.succeed(response);\n }\n }),\n );\n\n/**\n * Makes an authenticated HTTP request to a YouTube API endpoint.\n */\nconst makeYouTubeApiRequest = Effect.fn('makeYouTubeApiRequest')(function* (url: string) {\n const token = yield* GoogleCredentials.get();\n\n const httpClient = yield* HttpClient.HttpClient.pipe(Effect.map(withAuthorization(token, 'Bearer')));\n const httpClientWithTracerDisabled = httpClient.pipe(HttpClient.withTracerDisabledWhen(() => true));\n\n const request = HttpClientRequest.get(url);\n\n const response = yield* request.pipe(\n HttpClientRequest.setHeader('accept', 'application/json'),\n httpClientWithTracerDisabled.execute,\n Effect.flatMap((res) => res.json),\n Effect.timeout('10 seconds'),\n Effect.retry(Schedule.exponential(1_000).pipe(Schedule.compose(Schedule.recurs(3)))),\n Effect.scoped,\n Effect.withSpan('YouTubeApiRequest'),\n );\n\n if ((response as Record<string, unknown>).error) {\n log.catch((response as Record<string, unknown>).error);\n }\n\n return response;\n});\n\n/**\n * Get channel details by channel ID.\n * https://developers.google.com/youtube/v3/docs/channels/list\n */\nexport const getChannel = Effect.fn(function* (channelId: string) {\n const url = createUrl([API_URL, 'channels'], {\n part: 'snippet,contentDetails',\n id: channelId,\n }).toString();\n return yield* makeYouTubeApiRequest(url).pipe(Effect.flatMap(decodeAndHandleErrors(ChannelsResponse)));\n});\n\n/**\n * Get channel by username/handle.\n * https://developers.google.com/youtube/v3/docs/channels/list\n */\nexport const getChannelByHandle = Effect.fn(function* (handle: string) {\n const url = createUrl([API_URL, 'channels'], {\n part: 'snippet,contentDetails',\n forHandle: handle.startsWith('@') ? handle.slice(1) : handle,\n }).toString();\n return yield* makeYouTubeApiRequest(url).pipe(Effect.flatMap(decodeAndHandleErrors(ChannelsResponse)));\n});\n\n/**\n * Search for channels by query.\n * https://developers.google.com/youtube/v3/docs/search/list\n */\nexport const searchChannels = Effect.fn(function* (query: string, maxResults = 10) {\n const url = createUrl([API_URL, 'search'], {\n part: 'snippet',\n type: 'channel',\n q: query,\n maxResults,\n }).toString();\n return yield* makeYouTubeApiRequest(url).pipe(Effect.flatMap(decodeAndHandleErrors(SearchResponse)));\n});\n\n/**\n * List videos from a playlist (used to get uploads from a channel's uploads playlist).\n * https://developers.google.com/youtube/v3/docs/playlistItems/list\n */\nexport const listPlaylistItems = Effect.fn(function* (playlistId: string, maxResults = 50, pageToken?: string) {\n const url = createUrl([API_URL, 'playlistItems'], {\n part: 'snippet,contentDetails',\n playlistId,\n maxResults,\n pageToken,\n }).toString();\n return yield* makeYouTubeApiRequest(url).pipe(Effect.flatMap(decodeAndHandleErrors(PlaylistItemsResponse)));\n});\n\n/**\n * Get detailed video information including statistics and duration.\n * https://developers.google.com/youtube/v3/docs/videos/list\n */\nexport const getVideoDetails = Effect.fn(function* (videoIds: string[]) {\n const url = createUrl([API_URL, 'videos'], {\n part: 'snippet,contentDetails,statistics',\n id: videoIds.join(','),\n }).toString();\n return yield* makeYouTubeApiRequest(url).pipe(Effect.flatMap(decodeAndHandleErrors(VideosResponse)));\n});\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\n/**\n * YouTube API error response.\n */\nexport class YouTubeError extends Schema.TaggedError<YouTubeError>()('YouTubeError', {\n code: Schema.Number,\n message: Schema.String,\n status: Schema.optional(Schema.String),\n}) {\n static fromErrorResponse(response: ErrorResponse) {\n return new YouTubeError({\n code: response.error.code,\n message: response.error.message,\n status: response.error.status,\n });\n }\n}\n\nexport const ErrorResponse = Schema.Struct({\n error: Schema.Struct({\n code: Schema.Number,\n message: Schema.String,\n status: Schema.optional(Schema.String),\n }),\n});\n\nexport type ErrorResponse = Schema.Schema.Type<typeof ErrorResponse>;\n\n/**\n * YouTube channel snippet from search/channel API.\n */\nexport const ChannelSnippet = Schema.Struct({\n title: Schema.String,\n description: Schema.optional(Schema.String),\n customUrl: Schema.optional(Schema.String),\n publishedAt: Schema.optional(Schema.String),\n thumbnails: Schema.optional(\n Schema.Struct({\n default: Schema.optional(Schema.Struct({ url: Schema.String })),\n medium: Schema.optional(Schema.Struct({ url: Schema.String })),\n high: Schema.optional(Schema.Struct({ url: Schema.String })),\n }),\n ),\n});\n\n/**\n * YouTube channel item from channels API.\n */\nexport const ChannelItem = Schema.Struct({\n kind: Schema.String,\n etag: Schema.String,\n id: Schema.String,\n snippet: Schema.optional(ChannelSnippet),\n contentDetails: Schema.optional(\n Schema.Struct({\n relatedPlaylists: Schema.optional(\n Schema.Struct({\n uploads: Schema.optional(Schema.String),\n }),\n ),\n }),\n ),\n});\n\n/**\n * YouTube channels list response.\n */\nexport const ChannelsResponse = Schema.Struct({\n kind: Schema.String,\n etag: Schema.String,\n pageInfo: Schema.optional(\n Schema.Struct({\n totalResults: Schema.Number,\n resultsPerPage: Schema.Number,\n }),\n ),\n items: Schema.Array(ChannelItem),\n});\n\nexport type ChannelsResponse = Schema.Schema.Type<typeof ChannelsResponse>;\n\n/**\n * Video snippet from search/playlistItems API.\n */\nexport const VideoSnippet = Schema.Struct({\n publishedAt: Schema.String,\n channelId: Schema.optional(Schema.String),\n title: Schema.String,\n description: Schema.optional(Schema.String),\n thumbnails: Schema.optional(\n Schema.Struct({\n default: Schema.optional(Schema.Struct({ url: Schema.String })),\n medium: Schema.optional(Schema.Struct({ url: Schema.String })),\n high: Schema.optional(Schema.Struct({ url: Schema.String })),\n standard: Schema.optional(Schema.Struct({ url: Schema.String })),\n maxres: Schema.optional(Schema.Struct({ url: Schema.String })),\n }),\n ),\n channelTitle: Schema.optional(Schema.String),\n playlistId: Schema.optional(Schema.String),\n position: Schema.optional(Schema.Number),\n resourceId: Schema.optional(\n Schema.Struct({\n kind: Schema.String,\n videoId: Schema.String,\n }),\n ),\n});\n\n/**\n * Content details for a video.\n */\nexport const VideoContentDetails = Schema.Struct({\n videoId: Schema.optional(Schema.String),\n videoPublishedAt: Schema.optional(Schema.String),\n duration: Schema.optional(Schema.String),\n});\n\n/**\n * Video statistics.\n */\nexport const VideoStatistics = Schema.Struct({\n viewCount: Schema.optional(Schema.String),\n likeCount: Schema.optional(Schema.String),\n commentCount: Schema.optional(Schema.String),\n});\n\n/**\n * Video item from videos API.\n */\nexport const VideoItem = Schema.Struct({\n kind: Schema.String,\n etag: Schema.String,\n id: Schema.String,\n snippet: Schema.optional(VideoSnippet),\n contentDetails: Schema.optional(VideoContentDetails),\n statistics: Schema.optional(VideoStatistics),\n});\n\nexport type VideoItem = Schema.Schema.Type<typeof VideoItem>;\n\n/**\n * YouTube videos list response.\n */\nexport const VideosResponse = Schema.Struct({\n kind: Schema.String,\n etag: Schema.String,\n nextPageToken: Schema.optional(Schema.String),\n prevPageToken: Schema.optional(Schema.String),\n pageInfo: Schema.optional(\n Schema.Struct({\n totalResults: Schema.Number,\n resultsPerPage: Schema.Number,\n }),\n ),\n items: Schema.Array(VideoItem),\n});\n\nexport type VideosResponse = Schema.Schema.Type<typeof VideosResponse>;\n\n/**\n * Playlist item from playlistItems API.\n */\nexport const PlaylistItem = Schema.Struct({\n kind: Schema.String,\n etag: Schema.String,\n id: Schema.String,\n snippet: Schema.optional(VideoSnippet),\n contentDetails: Schema.optional(VideoContentDetails),\n});\n\n/**\n * YouTube playlist items response.\n */\nexport const PlaylistItemsResponse = Schema.Struct({\n kind: Schema.String,\n etag: Schema.String,\n nextPageToken: Schema.optional(Schema.String),\n prevPageToken: Schema.optional(Schema.String),\n pageInfo: Schema.optional(\n Schema.Struct({\n totalResults: Schema.Number,\n resultsPerPage: Schema.Number,\n }),\n ),\n items: Schema.Array(PlaylistItem),\n});\n\nexport type PlaylistItemsResponse = Schema.Schema.Type<typeof PlaylistItemsResponse>;\n\n/**\n * Search result item.\n */\nexport const SearchItem = Schema.Struct({\n kind: Schema.String,\n etag: Schema.String,\n id: Schema.Struct({\n kind: Schema.String,\n videoId: Schema.optional(Schema.String),\n channelId: Schema.optional(Schema.String),\n playlistId: Schema.optional(Schema.String),\n }),\n snippet: Schema.optional(VideoSnippet),\n});\n\n/**\n * YouTube search response.\n */\nexport const SearchResponse = Schema.Struct({\n kind: Schema.String,\n etag: Schema.String,\n nextPageToken: Schema.optional(Schema.String),\n prevPageToken: Schema.optional(Schema.String),\n pageInfo: Schema.optional(\n Schema.Struct({\n totalResults: Schema.Number,\n resultsPerPage: Schema.Number,\n }),\n ),\n items: Schema.Array(SearchItem),\n});\n\nexport type SearchResponse = Schema.Schema.Type<typeof SearchResponse>;\n\n/**\n * Caption track from captions.list.\n */\nexport const CaptionResource = Schema.Struct({\n id: Schema.String,\n snippet: Schema.optional(\n Schema.Struct({\n videoId: Schema.optional(Schema.String),\n language: Schema.optional(Schema.String),\n name: Schema.optional(Schema.String),\n trackKind: Schema.optional(Schema.String),\n }),\n ),\n});\n\n/**\n * YouTube captions.list response.\n */\nexport const CaptionsListResponse = Schema.Struct({\n kind: Schema.String,\n etag: Schema.String,\n items: Schema.optional(Schema.Array(CaptionResource)),\n});\n\nexport type CaptionsListResponse = Schema.Schema.Type<typeof CaptionsListResponse>;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Context", "Effect", "Layer", "Database", "CredentialsService", "log", "makeService", "cachedToken", "get", "succeed", "map", "getCredential", "service", "credential", "apiKey", "loadAccessToken", "accessTokenRef", "label", "gen", "accessToken", "load", "token", "note", "undefined", "GoogleCredentials", "Tag", "fromChannel", "channel", "effect", "fromChannelRef", "channelRef", "flatMap", "default", "HttpClient", "HttpClientRequest", "Effect", "Schedule", "Schema", "withAuthorization", "log", "Schema", "YouTubeError", "TaggedError", "code", "Number", "message", "String", "status", "optional", "fromErrorResponse", "response", "error", "ErrorResponse", "Struct", "ChannelSnippet", "title", "description", "customUrl", "publishedAt", "thumbnails", "default", "url", "medium", "high", "ChannelItem", "kind", "etag", "id", "snippet", "contentDetails", "relatedPlaylists", "uploads", "ChannelsResponse", "pageInfo", "totalResults", "resultsPerPage", "items", "Array", "VideoSnippet", "channelId", "standard", "maxres", "channelTitle", "playlistId", "position", "resourceId", "videoId", "VideoContentDetails", "videoPublishedAt", "duration", "VideoStatistics", "viewCount", "likeCount", "commentCount", "VideoItem", "statistics", "VideosResponse", "nextPageToken", "prevPageToken", "PlaylistItem", "PlaylistItemsResponse", "SearchItem", "SearchResponse", "CaptionResource", "language", "name", "trackKind", "CaptionsListResponse", "API_URL", "createUrl", "parts", "params", "url", "URL", "filter", "Boolean", "join", "Object", "entries", "_", "value", "forEach", "key", "searchParams", "set", "String", "decodeAndHandleErrors", "schema", "data", "decodeUnknown", "Union", "ErrorResponse", "pipe", "flatMap", "response", "fail", "YouTubeError", "fromErrorResponse", "succeed", "makeYouTubeApiRequest", "fn", "token", "GoogleCredentials", "get", "httpClient", "HttpClient", "map", "withAuthorization", "httpClientWithTracerDisabled", "withTracerDisabledWhen", "request", "setHeader", "execute", "res", "json", "timeout", "retry", "exponential", "compose", "recurs", "scoped", "withSpan", "error", "log", "catch", "getChannel", "channelId", "part", "id", "toString", "ChannelsResponse", "getChannelByHandle", "handle", "forHandle", "startsWith", "slice", "searchChannels", "query", "maxResults", "type", "q", "SearchResponse", "listPlaylistItems", "playlistId", "pageToken", "PlaylistItemsResponse", "getVideoDetails", "videoIds", "VideosResponse"]
|
|
7
|
+
}
|