@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.
Files changed (199) hide show
  1. package/LICENSE +21 -0
  2. package/dist/lib/browser/ChannelArticle-CDQR4BBY.mjs +90 -0
  3. package/dist/lib/browser/ChannelArticle-CDQR4BBY.mjs.map +7 -0
  4. package/dist/lib/browser/ChannelSettings-ZYUNW3VS.mjs +28 -0
  5. package/dist/lib/browser/ChannelSettings-ZYUNW3VS.mjs.map +7 -0
  6. package/dist/lib/browser/VideoArticle-FC4A6E7B.mjs +76 -0
  7. package/dist/lib/browser/VideoArticle-FC4A6E7B.mjs.map +7 -0
  8. package/dist/lib/browser/VideoCard-CCPXDCB7.mjs +64 -0
  9. package/dist/lib/browser/VideoCard-CCPXDCB7.mjs.map +7 -0
  10. package/dist/lib/browser/app-graph-builder-MJY6A6SN.mjs +195 -0
  11. package/dist/lib/browser/app-graph-builder-MJY6A6SN.mjs.map +7 -0
  12. package/dist/lib/browser/blueprint-definition-FRYUYJ22.mjs +22 -0
  13. package/dist/lib/browser/blueprint-definition-FRYUYJ22.mjs.map +7 -0
  14. package/dist/lib/browser/blueprints/index.mjs +13 -0
  15. package/dist/lib/browser/blueprints/index.mjs.map +7 -0
  16. package/dist/lib/browser/chunk-C26XKDK2.mjs +355 -0
  17. package/dist/lib/browser/chunk-C26XKDK2.mjs.map +7 -0
  18. package/dist/lib/browser/chunk-DFRSBBSO.mjs +21 -0
  19. package/dist/lib/browser/chunk-DFRSBBSO.mjs.map +7 -0
  20. package/dist/lib/browser/chunk-GFRR4TTX.mjs +72 -0
  21. package/dist/lib/browser/chunk-GFRR4TTX.mjs.map +7 -0
  22. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  23. package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +7 -0
  24. package/dist/lib/browser/chunk-MUE22YUM.mjs +57 -0
  25. package/dist/lib/browser/chunk-MUE22YUM.mjs.map +7 -0
  26. package/dist/lib/browser/chunk-P67QEKBQ.mjs +72 -0
  27. package/dist/lib/browser/chunk-P67QEKBQ.mjs.map +7 -0
  28. package/dist/lib/browser/chunk-YMDT37TA.mjs +62 -0
  29. package/dist/lib/browser/chunk-YMDT37TA.mjs.map +7 -0
  30. package/dist/lib/browser/chunk-Z3DGTMKC.mjs +8 -0
  31. package/dist/lib/browser/chunk-Z3DGTMKC.mjs.map +7 -0
  32. package/dist/lib/browser/clear-synced-videos-EVMJIZPD.mjs +66 -0
  33. package/dist/lib/browser/clear-synced-videos-EVMJIZPD.mjs.map +7 -0
  34. package/dist/lib/browser/index.mjs +153 -0
  35. package/dist/lib/browser/index.mjs.map +7 -0
  36. package/dist/lib/browser/meta.json +1 -0
  37. package/dist/lib/browser/react-surface-EDA5VYDC.mjs +77 -0
  38. package/dist/lib/browser/react-surface-EDA5VYDC.mjs.map +7 -0
  39. package/dist/lib/browser/sync-423Q4BDD.mjs +360 -0
  40. package/dist/lib/browser/sync-423Q4BDD.mjs.map +7 -0
  41. package/dist/lib/browser/types/index.mjs +14 -0
  42. package/dist/lib/browser/types/index.mjs.map +7 -0
  43. package/dist/lib/node-esm/ChannelArticle-GQ64BO7V.mjs +91 -0
  44. package/dist/lib/node-esm/ChannelArticle-GQ64BO7V.mjs.map +7 -0
  45. package/dist/lib/node-esm/ChannelSettings-DM2HWNKO.mjs +29 -0
  46. package/dist/lib/node-esm/ChannelSettings-DM2HWNKO.mjs.map +7 -0
  47. package/dist/lib/node-esm/VideoArticle-WLTWZO3K.mjs +77 -0
  48. package/dist/lib/node-esm/VideoArticle-WLTWZO3K.mjs.map +7 -0
  49. package/dist/lib/node-esm/VideoCard-FOWQZK75.mjs +65 -0
  50. package/dist/lib/node-esm/VideoCard-FOWQZK75.mjs.map +7 -0
  51. package/dist/lib/node-esm/app-graph-builder-IU5TBAXN.mjs +196 -0
  52. package/dist/lib/node-esm/app-graph-builder-IU5TBAXN.mjs.map +7 -0
  53. package/dist/lib/node-esm/blueprint-definition-W264MZ3D.mjs +23 -0
  54. package/dist/lib/node-esm/blueprint-definition-W264MZ3D.mjs.map +7 -0
  55. package/dist/lib/node-esm/blueprints/index.mjs +14 -0
  56. package/dist/lib/node-esm/blueprints/index.mjs.map +7 -0
  57. package/dist/lib/node-esm/chunk-5KNC2JMP.mjs +58 -0
  58. package/dist/lib/node-esm/chunk-5KNC2JMP.mjs.map +7 -0
  59. package/dist/lib/node-esm/chunk-6BUJ2DQX.mjs +73 -0
  60. package/dist/lib/node-esm/chunk-6BUJ2DQX.mjs.map +7 -0
  61. package/dist/lib/node-esm/chunk-CX6MV3QM.mjs +23 -0
  62. package/dist/lib/node-esm/chunk-CX6MV3QM.mjs.map +7 -0
  63. package/dist/lib/node-esm/chunk-CZSLL3XQ.mjs +63 -0
  64. package/dist/lib/node-esm/chunk-CZSLL3XQ.mjs.map +7 -0
  65. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  66. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  67. package/dist/lib/node-esm/chunk-JM5SBBP5.mjs +356 -0
  68. package/dist/lib/node-esm/chunk-JM5SBBP5.mjs.map +7 -0
  69. package/dist/lib/node-esm/chunk-JSGRZMG3.mjs +73 -0
  70. package/dist/lib/node-esm/chunk-JSGRZMG3.mjs.map +7 -0
  71. package/dist/lib/node-esm/chunk-M4S6BE47.mjs +10 -0
  72. package/dist/lib/node-esm/chunk-M4S6BE47.mjs.map +7 -0
  73. package/dist/lib/node-esm/clear-synced-videos-5UCH6XHL.mjs +67 -0
  74. package/dist/lib/node-esm/clear-synced-videos-5UCH6XHL.mjs.map +7 -0
  75. package/dist/lib/node-esm/index.mjs +154 -0
  76. package/dist/lib/node-esm/index.mjs.map +7 -0
  77. package/dist/lib/node-esm/meta.json +1 -0
  78. package/dist/lib/node-esm/react-surface-5DJAQPHJ.mjs +78 -0
  79. package/dist/lib/node-esm/react-surface-5DJAQPHJ.mjs.map +7 -0
  80. package/dist/lib/node-esm/sync-CEF5DX2J.mjs +361 -0
  81. package/dist/lib/node-esm/sync-CEF5DX2J.mjs.map +7 -0
  82. package/dist/lib/node-esm/types/index.mjs +15 -0
  83. package/dist/lib/node-esm/types/index.mjs.map +7 -0
  84. package/dist/types/src/YouTubePlugin.d.ts +3 -0
  85. package/dist/types/src/YouTubePlugin.d.ts.map +1 -0
  86. package/dist/types/src/blueprints/index.d.ts +3 -0
  87. package/dist/types/src/blueprints/index.d.ts.map +1 -0
  88. package/dist/types/src/blueprints/youtube.d.ts +4 -0
  89. package/dist/types/src/blueprints/youtube.d.ts.map +1 -0
  90. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +6 -0
  91. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +1 -0
  92. package/dist/types/src/capabilities/app-graph-builder/index.d.ts +3 -0
  93. package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +1 -0
  94. package/dist/types/src/capabilities/blueprint-definition/blueprint-definition.d.ts +6 -0
  95. package/dist/types/src/capabilities/blueprint-definition/blueprint-definition.d.ts.map +1 -0
  96. package/dist/types/src/capabilities/blueprint-definition/index.d.ts +3 -0
  97. package/dist/types/src/capabilities/blueprint-definition/index.d.ts.map +1 -0
  98. package/dist/types/src/capabilities/index.d.ts +4 -0
  99. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  100. package/dist/types/src/capabilities/react-surface/index.d.ts +3 -0
  101. package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -0
  102. package/dist/types/src/capabilities/react-surface/react-surface.d.ts +5 -0
  103. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -0
  104. package/dist/types/src/containers/ChannelArticle/ChannelArticle.d.ts +8 -0
  105. package/dist/types/src/containers/ChannelArticle/ChannelArticle.d.ts.map +1 -0
  106. package/dist/types/src/containers/ChannelArticle/index.d.ts +3 -0
  107. package/dist/types/src/containers/ChannelArticle/index.d.ts.map +1 -0
  108. package/dist/types/src/containers/ChannelSettings/ChannelSettings.d.ts +7 -0
  109. package/dist/types/src/containers/ChannelSettings/ChannelSettings.d.ts.map +1 -0
  110. package/dist/types/src/containers/ChannelSettings/index.d.ts +3 -0
  111. package/dist/types/src/containers/ChannelSettings/index.d.ts.map +1 -0
  112. package/dist/types/src/containers/VideoArticle/VideoArticle.d.ts +11 -0
  113. package/dist/types/src/containers/VideoArticle/VideoArticle.d.ts.map +1 -0
  114. package/dist/types/src/containers/VideoArticle/index.d.ts +3 -0
  115. package/dist/types/src/containers/VideoArticle/index.d.ts.map +1 -0
  116. package/dist/types/src/containers/VideoCard/VideoCard.d.ts +9 -0
  117. package/dist/types/src/containers/VideoCard/VideoCard.d.ts.map +1 -0
  118. package/dist/types/src/containers/VideoCard/index.d.ts +3 -0
  119. package/dist/types/src/containers/VideoCard/index.d.ts.map +1 -0
  120. package/dist/types/src/containers/index.d.ts +11 -0
  121. package/dist/types/src/containers/index.d.ts.map +1 -0
  122. package/dist/types/src/index.d.ts +4 -0
  123. package/dist/types/src/index.d.ts.map +1 -0
  124. package/dist/types/src/meta.d.ts +3 -0
  125. package/dist/types/src/meta.d.ts.map +1 -0
  126. package/dist/types/src/operations/apis/index.d.ts +2 -0
  127. package/dist/types/src/operations/apis/index.d.ts.map +1 -0
  128. package/dist/types/src/operations/apis/youtube/api.d.ts +251 -0
  129. package/dist/types/src/operations/apis/youtube/api.d.ts.map +1 -0
  130. package/dist/types/src/operations/apis/youtube/index.d.ts +3 -0
  131. package/dist/types/src/operations/apis/youtube/index.d.ts.map +1 -0
  132. package/dist/types/src/operations/apis/youtube/types.d.ts +493 -0
  133. package/dist/types/src/operations/apis/youtube/types.d.ts.map +1 -0
  134. package/dist/types/src/operations/clear-synced-videos.d.ts +5 -0
  135. package/dist/types/src/operations/clear-synced-videos.d.ts.map +1 -0
  136. package/dist/types/src/operations/definitions.d.ts +45 -0
  137. package/dist/types/src/operations/definitions.d.ts.map +1 -0
  138. package/dist/types/src/operations/index.d.ts +5 -0
  139. package/dist/types/src/operations/index.d.ts.map +1 -0
  140. package/dist/types/src/operations/services/google-credentials.d.ts +35 -0
  141. package/dist/types/src/operations/services/google-credentials.d.ts.map +1 -0
  142. package/dist/types/src/operations/services/index.d.ts +2 -0
  143. package/dist/types/src/operations/services/index.d.ts.map +1 -0
  144. package/dist/types/src/operations/sync.d.ts +5 -0
  145. package/dist/types/src/operations/sync.d.ts.map +1 -0
  146. package/dist/types/src/operations/sync.test.d.ts +2 -0
  147. package/dist/types/src/operations/sync.test.d.ts.map +1 -0
  148. package/dist/types/src/operations/transcript.d.ts +12 -0
  149. package/dist/types/src/operations/transcript.d.ts.map +1 -0
  150. package/dist/types/src/translations.d.ts +49 -0
  151. package/dist/types/src/translations.d.ts.map +1 -0
  152. package/dist/types/src/types/Channel.d.ts +54 -0
  153. package/dist/types/src/types/Channel.d.ts.map +1 -0
  154. package/dist/types/src/types/Video.d.ts +41 -0
  155. package/dist/types/src/types/Video.d.ts.map +1 -0
  156. package/dist/types/src/types/index.d.ts +4 -0
  157. package/dist/types/src/types/index.d.ts.map +1 -0
  158. package/dist/types/src/types/types.d.ts +5 -0
  159. package/dist/types/src/types/types.d.ts.map +1 -0
  160. package/dist/types/tsconfig.tsbuildinfo +1 -0
  161. package/package.json +113 -0
  162. package/src/YouTubePlugin.tsx +66 -0
  163. package/src/blueprints/index.ts +7 -0
  164. package/src/blueprints/youtube.ts +52 -0
  165. package/src/capabilities/app-graph-builder/app-graph-builder.ts +148 -0
  166. package/src/capabilities/app-graph-builder/index.ts +7 -0
  167. package/src/capabilities/blueprint-definition/blueprint-definition.ts +17 -0
  168. package/src/capabilities/blueprint-definition/index.ts +7 -0
  169. package/src/capabilities/index.ts +7 -0
  170. package/src/capabilities/react-surface/index.ts +7 -0
  171. package/src/capabilities/react-surface/react-surface.tsx +54 -0
  172. package/src/containers/ChannelArticle/ChannelArticle.tsx +115 -0
  173. package/src/containers/ChannelArticle/index.ts +7 -0
  174. package/src/containers/ChannelSettings/ChannelSettings.tsx +34 -0
  175. package/src/containers/ChannelSettings/index.ts +7 -0
  176. package/src/containers/VideoArticle/VideoArticle.tsx +109 -0
  177. package/src/containers/VideoArticle/index.ts +7 -0
  178. package/src/containers/VideoCard/VideoCard.tsx +86 -0
  179. package/src/containers/VideoCard/index.ts +7 -0
  180. package/src/containers/index.ts +24 -0
  181. package/src/index.ts +8 -0
  182. package/src/meta.ts +19 -0
  183. package/src/operations/apis/index.ts +5 -0
  184. package/src/operations/apis/youtube/api.ts +149 -0
  185. package/src/operations/apis/youtube/index.ts +6 -0
  186. package/src/operations/apis/youtube/types.ts +254 -0
  187. package/src/operations/clear-synced-videos.ts +50 -0
  188. package/src/operations/definitions.ts +62 -0
  189. package/src/operations/index.ts +13 -0
  190. package/src/operations/services/google-credentials.ts +81 -0
  191. package/src/operations/services/index.ts +5 -0
  192. package/src/operations/sync.test.ts +114 -0
  193. package/src/operations/sync.ts +309 -0
  194. package/src/operations/transcript.ts +47 -0
  195. package/src/translations.ts +59 -0
  196. package/src/types/Channel.ts +80 -0
  197. package/src/types/Video.ts +67 -0
  198. package/src/types/index.ts +8 -0
  199. 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,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -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
+ }