@particle-academy/google-slides-ui 0.3.4 → 0.5.0

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/CHANGELOG.md CHANGED
@@ -8,6 +8,39 @@ The four packages share one version, because they are generated from one
8
8
  `provider/` definition and a version that meant something different in each
9
9
  would be a version nobody could reason about.
10
10
 
11
+ ## [0.5.0] — 2026-11-08
12
+
13
+ ### Added
14
+
15
+ - **Laravel integration, in this package** (`src/Laravel/`), auto-discovered
16
+ through composer's `extra.laravel`. Laravel is SUGGESTED, never required:
17
+ outside a Laravel app none of it loads.
18
+ - a service provider that merges `config/google-slides.php` under
19
+ `connectors.google-slides` (credentials from the environment, or per call for a
20
+ multi-account app);
21
+ - the `GoogleSlides` facade: `GoogleSlides::call('<operation>', [...])` runs any action;
22
+ - `GoogleSlides::fake()`, answered from the connector's faker, with
23
+ `assertSent` / `assertNotSent` / `assertNothingSent` / `assertSentCount`;
24
+ - its own Pest test of all of it against a booted Laravel app.
25
+
26
+ ### Changed
27
+
28
+ - **Tests: Pest `^5`**, and `laravel/framework` `^13` as a DEV-ONLY test
29
+ dependency (the framework this package integrates with; nothing ships in
30
+ `require`).
31
+
32
+ ## [0.4.0] — 2026-10-01
33
+
34
+ ### Added
35
+
36
+ - **`presentation_get`** — read a presentation's slides and the objectId
37
+ of every element on them. No scope change. This is the prerequisite
38
+ for targeting a specific shape or placeholder with a future edit —
39
+ `presentations.batchUpdate` operates on objectIds, and until now there
40
+ was no way to discover one. `insertText`-style editing is NOT included
41
+ yet; it is a natural next step once this read side exists, not
42
+ bundled in here.
43
+
11
44
  ## [0.3.4] — 2026-09-12
12
45
 
13
46
  ### Changed
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Google Slides
2
2
 
3
+ [![Fancified](art/fancified.svg)](https://particle.academy)
4
+
3
5
  Google Slides for [fancy-flow][flow] — as **four imported, versioned packages**, one
4
6
  per runtime. Not vendored source: a copy cannot be upgraded, and third-party APIs
5
7
  change.
@@ -75,6 +77,16 @@ Create a blank Google Slides presentation.
75
77
  |---|---|---|
76
78
  | `title` | yes | The title of the new blank presentation. |
77
79
 
80
+ #### `presentation_get` — Google Slides presentation
81
+
82
+ Read a presentation's slides and the objectId of every element on them -- the prerequisite for targeting a specific shape or placeholder with a future edit.
83
+
84
+ `GET /v1/presentations/{presentationId}` · reads only — safe to replay
85
+
86
+ | Input | Required | What it is |
87
+ |---|---|---|
88
+ | `presentationId` | yes | From presentation_create's data.presentationId, or the id in the presentation's own URL. |
89
+
78
90
  ## Run it before you have credentials
79
91
 
80
92
  Every operation ships a **faker**, whether or not Google Slides has a sandbox. Set a
@@ -0,0 +1,26 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="128" height="28" role="img" aria-label="Fancified — built with Fancy UI">
2
+ <title>Fancified · built with Fancy UI</title>
3
+ <defs>
4
+ <linearGradient id="fcdBg" x1="0" y1="0" x2="1" y2="1">
5
+ <stop offset="0" stop-color="#6d28d9"/>
6
+ <stop offset=".5" stop-color="#9333ea"/>
7
+ <stop offset="1" stop-color="#d946ef"/>
8
+ </linearGradient>
9
+ <linearGradient id="fcdGloss" x1="0" y1="0" x2="0" y2="1">
10
+ <stop offset="0" stop-color="#ffffff" stop-opacity=".30"/>
11
+ <stop offset=".55" stop-color="#ffffff" stop-opacity="0"/>
12
+ </linearGradient>
13
+ <clipPath id="fcdClip"><rect width="128" height="28" rx="7"/></clipPath>
14
+ </defs>
15
+ <g clip-path="url(#fcdClip)">
16
+ <rect width="128" height="28" fill="url(#fcdBg)"/>
17
+ <rect width="34" height="28" fill="#3b0764" fill-opacity=".5"/>
18
+ <rect width="128" height="13" fill="url(#fcdGloss)"/>
19
+ <g fill="#fff">
20
+ <path transform="translate(17 14)" d="M0 -7 C.6 -2.2 2.2 -.6 7 0 C2.2 .6 .6 2.2 0 7 C-.6 2.2 -2.2 .6 -7 0 C-2.2 -.6 -.6 -2.2 0 -7 Z"/>
21
+ <path transform="translate(25.5 7.5) scale(.34)" fill-opacity=".85" d="M0 -7 C.6 -2.2 2.2 -.6 7 0 C2.2 .6 .6 2.2 0 7 C-.6 2.2 -2.2 .6 -7 0 C-2.2 -.6 -.6 -2.2 0 -7 Z"/>
22
+ </g>
23
+ <text x="81" y="18.5" fill="#ffffff" text-anchor="middle" font-family="'Segoe UI',Verdana,'DejaVu Sans',sans-serif" font-size="12" font-weight="700" letter-spacing=".3">Fancified</text>
24
+ </g>
25
+ <rect x=".5" y=".5" width="127" height="27" rx="6.5" fill="none" stroke="#ffffff" stroke-opacity=".22"/>
26
+ </svg>
package/dist/index.cjs CHANGED
@@ -93,22 +93,81 @@ var googleSlidesPresentationKind = connectors.defineConnectorKind(GOOGLE_SLIDES_
93
93
  },
94
94
  renderBody: ({ config }) => connectors.summarize(GOOGLE_SLIDES_PRESENTATION_META, config, "create a blank presentation")
95
95
  });
96
+ var GOOGLE_SLIDES_PRESENTATION_GET_KIND = "@particle-academy/google_slides_presentation_get";
97
+ var GOOGLE_SLIDES_PRESENTATION_GET_OPERATION = "presentation_get";
98
+ var GOOGLE_SLIDES_PRESENTATION_GET_META = googleSlidesMeta("action", "read a presentation", "https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/get");
99
+ var GOOGLE_SLIDES_PRESENTATION_GET_OUTPUT = [
100
+ {
101
+ "path": "data.presentationId",
102
+ "type": "string",
103
+ "description": "Echoes what was asked."
104
+ },
105
+ {
106
+ "path": "data.title",
107
+ "type": "string",
108
+ "description": "The presentation's title."
109
+ },
110
+ {
111
+ "path": "data.locale",
112
+ "type": "string",
113
+ "description": "BCP 47 language tag."
114
+ },
115
+ {
116
+ "path": "data.slides",
117
+ "type": "array",
118
+ "description": "One entry per slide, in order: objectId, and pageElements -- each with its own objectId and exactly one of shape/image/table/line/video/wordArt/sheetsChart/elementGroup/speakerSpotlight set, naming what kind of element it is. A placeholder shape's text (when it has one) lives at pageElements[].shape.text, published raw -- this connector does not flatten Slides' own rich-text run structure."
119
+ },
120
+ {
121
+ "path": "mode",
122
+ "type": "string",
123
+ "description": "Which estate this ran against. Google has no sandbox, so: fake or live."
124
+ }
125
+ ];
126
+ var googleSlidesPresentationGetKind = connectors.defineConnectorKind(GOOGLE_SLIDES_PRESENTATION_GET_META, {
127
+ name: GOOGLE_SLIDES_PRESENTATION_GET_KIND,
128
+ aliases: ["google_slides_presentation_get"],
129
+ label: "Google Slides presentation",
130
+ description: "Read a presentation's slides and the objectId of every element on them -- the prerequisite for targeting a specific shape or placeholder with a future edit.",
131
+ inputs: [{ id: "in" }],
132
+ outputs: [{ id: "out" }],
133
+ sideEffects: "none",
134
+ outputShape: GOOGLE_SLIDES_PRESENTATION_GET_OUTPUT,
135
+ configSchema: [
136
+ {
137
+ "type": "text",
138
+ "key": "presentationId",
139
+ "label": "Presentation ID",
140
+ "required": true,
141
+ "description": "From presentation_create's data.presentationId, or the id in the presentation's own URL."
142
+ }
143
+ ],
144
+ defaultConfig: {
145
+ "mode": "auto"
146
+ },
147
+ renderBody: ({ config }) => connectors.summarize(GOOGLE_SLIDES_PRESENTATION_GET_META, config, "read a presentation")
148
+ });
96
149
 
97
150
  // src/index.ts
98
151
  var GOOGLE_SLIDES_KINDS = [
99
- googleSlidesPresentationKind
152
+ googleSlidesPresentationKind,
153
+ googleSlidesPresentationGetKind
100
154
  ];
101
155
 
102
156
  exports.CONNECTOR_API_VERSION = CONNECTOR_API_VERSION;
103
157
  exports.GOOGLE_SLIDES_CREDENTIALS = GOOGLE_SLIDES_CREDENTIALS;
104
158
  exports.GOOGLE_SLIDES_KINDS = GOOGLE_SLIDES_KINDS;
105
159
  exports.GOOGLE_SLIDES_OAUTH = GOOGLE_SLIDES_OAUTH;
160
+ exports.GOOGLE_SLIDES_PRESENTATION_GET_KIND = GOOGLE_SLIDES_PRESENTATION_GET_KIND;
161
+ exports.GOOGLE_SLIDES_PRESENTATION_GET_META = GOOGLE_SLIDES_PRESENTATION_GET_META;
162
+ exports.GOOGLE_SLIDES_PRESENTATION_GET_OPERATION = GOOGLE_SLIDES_PRESENTATION_GET_OPERATION;
163
+ exports.GOOGLE_SLIDES_PRESENTATION_GET_OUTPUT = GOOGLE_SLIDES_PRESENTATION_GET_OUTPUT;
106
164
  exports.GOOGLE_SLIDES_PRESENTATION_KIND = GOOGLE_SLIDES_PRESENTATION_KIND;
107
165
  exports.GOOGLE_SLIDES_PRESENTATION_META = GOOGLE_SLIDES_PRESENTATION_META;
108
166
  exports.GOOGLE_SLIDES_PRESENTATION_OPERATION = GOOGLE_SLIDES_PRESENTATION_OPERATION;
109
167
  exports.GOOGLE_SLIDES_PRESENTATION_OUTPUT = GOOGLE_SLIDES_PRESENTATION_OUTPUT;
110
168
  exports.GOOGLE_SLIDES_SERVICE = GOOGLE_SLIDES_SERVICE;
111
169
  exports.googleSlidesMeta = googleSlidesMeta;
170
+ exports.googleSlidesPresentationGetKind = googleSlidesPresentationGetKind;
112
171
  exports.googleSlidesPresentationKind = googleSlidesPresentationKind;
113
172
  //# sourceMappingURL=index.cjs.map
114
173
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/service.ts","../src/kinds/presentation-create.ts","../src/index.ts"],"names":["defineConnectorKind","summarize"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/manifest.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/manifest.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- google_slides\n */\n\n/**\n * Google Slides's identity on the authoring surface, shared by every Google\n * Slides node.\n *\n * This file must import nothing from the js package: a PHP or Python project\n * installs the ui package and never that one, and the import would be a\n * dangling module the moment it did.\n *\n * ## The sandbox trap\n *\n * Google has no sandbox for Slides. A test presentation is a real one in a\n * real Drive, so every create is real -- use the faker while developing and\n * clean up any live test presentations.\n */\n\nimport type { ConnectorDomain, ConnectorMeta } from \"@particle-academy/fancy-flow/connectors\";\n\n/**\n * The connector API version this package was GENERATED against.\n *\n * A literal, never imported — an imported constant lets an upgrade rewrite the\n * very claim it exists to detect.\n */\nexport const CONNECTOR_API_VERSION = 1;\n\n/** The parts of a connector's identity that belong to the SERVICE, not the node. */\nexport const GOOGLE_SLIDES_SERVICE = {\n service: \"google_slides\",\n serviceTitle: \"Google Slides\",\n domain: \"productivity\",\n sandbox: \"none\",\n} as const satisfies Pick<ConnectorMeta, \"service\" | \"serviceTitle\" | \"domain\" | \"sandbox\">;\n\n/**\n * Every connector domain weaver knows, pinned against fancy-flow's union.\n *\n * A closed set copied into three codebases stays correct only while something\n * MAKES it: this line fails to compile the moment weaver carries a value\n * fancy-flow does not, including the values no provider uses yet.\n */\nconst WEAVER_DOMAINS: readonly ConnectorDomain[] = [\n \"payments\",\n \"commerce\",\n \"messaging\",\n \"email\",\n \"crm\",\n \"support\",\n \"storage\",\n \"calendar\",\n \"productivity\",\n \"database\",\n \"devtools\",\n \"analytics\",\n \"marketing\",\n \"ai\",\n \"forms\",\n \"hr\",\n \"geo\"\n];\nvoid WEAVER_DOMAINS;\n\n/** The credentials a Google Slides connection holds. */\nexport const GOOGLE_SLIDES_CREDENTIALS = [\n {\n \"key\": \"clientId\",\n \"label\": \"OAuth client ID\",\n \"scope\": \"provider\",\n \"secret\": false,\n \"help\": \"From Google Cloud Console -> APIs & Services -> Credentials. ONE value for the whole installation, not per connected account.\"\n },\n {\n \"key\": \"clientSecret\",\n \"label\": \"OAuth client secret\",\n \"scope\": \"provider\",\n \"secret\": true,\n \"help\": \"The client secret for the same OAuth app. One value for the whole installation.\"\n },\n {\n \"key\": \"accessToken\",\n \"label\": \"Access token\",\n \"scope\": \"account\",\n \"secret\": true,\n \"help\": \"Per connected Google account, and it expires after ONE HOUR. The host refreshes it with the refresh token.\"\n },\n {\n \"key\": \"refreshToken\",\n \"label\": \"Refresh token\",\n \"scope\": \"account\",\n \"secret\": true,\n \"help\": \"Per connected Google account. Google issues one only when the consent request asks for offline access; without it the connection dies within the hour.\"\n }\n] as const;\n\n/**\n * The OAuth2 exchange Google Slides requires — DECLARED here, performed by the\n * host.\n *\n * A consent screen needs a browser, a redirect URI and somewhere to persist\n * the result, and all three belong to the host; a package that ran the dance\n * itself would have to own a web server. So this says precisely enough for a\n * host to do it.\n *\n * The access token lasts 3600 seconds. A host that never refreshes will work\n * all afternoon and be broken by morning, which is why the lifetime is stated\n * rather than left to be discovered.\n *\n * Its refresh tokens do NOT rotate: the same one is reusable, so a refresh may\n * safely be retried and may run concurrently. That is stated rather than\n * assumed because the opposite — a provider that spends the token and revokes\n * the grant on a replay — looks identical until it happens.\n */\nexport const GOOGLE_SLIDES_OAUTH = {\n \"flow\": \"authorization_code\",\n \"authorizeUrl\": \"https://accounts.google.com/o/oauth2/v2/auth\",\n \"tokenUrl\": \"https://oauth2.googleapis.com/token\",\n \"scopes\": [\n \"https://www.googleapis.com/auth/presentations\"\n ],\n \"accessTokenCredential\": \"accessToken\",\n \"refreshTokenCredential\": \"refreshToken\",\n \"refreshTokenRotates\": false,\n \"accessTokenTtlSeconds\": 3600\n} as const;\n\n/** Build a Google Slides node's connector metadata from the operation it performs. */\nexport function googleSlidesMeta(\n role: ConnectorMeta[\"role\"],\n operation: string,\n docs: string,\n): ConnectorMeta {\n return { ...GOOGLE_SLIDES_SERVICE, role, operation, docs };\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/presentation-create.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/presentation-create.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- google_slides\n */\n\n/**\n * Google Slides presentation — Create a blank Google Slides presentation.\n *\n * https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/create\n *\n * `unsafe-to-replay`.\n */\n\nimport type { NodeKindDefinition } from \"@particle-academy/fancy-flow/engine\";\nimport { defineConnectorKind, summarize, type OutputField } from \"@particle-academy/fancy-flow/connectors\";\nimport { googleSlidesMeta } from \"../service.js\";\n\nexport const GOOGLE_SLIDES_PRESENTATION_KIND = \"@particle-academy/google_slides_presentation\";\nexport const GOOGLE_SLIDES_PRESENTATION_OPERATION = \"presentation_create\";\n\nexport const GOOGLE_SLIDES_PRESENTATION_META = googleSlidesMeta(\"action\", \"create a blank presentation\", \"https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/create\");\n\n/**\n * What this node emits — the \"ingredients\" a downstream node can reference.\n *\n * fancy-flow reads `outputShape` off the kind and offers it in the variable\n * picker, so declaring it is the whole of the work: an author configuring the\n * next node picks `{{ $json.data.id }}` off a list instead of typing a path\n * and hoping.\n */\nexport const GOOGLE_SLIDES_PRESENTATION_OUTPUT: OutputField[] = [\n {\n \"path\": \"data.presentationId\",\n \"type\": \"string\",\n \"description\": \"The id of the created presentation.\"\n },\n {\n \"path\": \"data.title\",\n \"type\": \"string\",\n \"description\": \"The title Google stored.\"\n }\n];\n\nexport const googleSlidesPresentationKind: NodeKindDefinition = defineConnectorKind(GOOGLE_SLIDES_PRESENTATION_META, {\n name: GOOGLE_SLIDES_PRESENTATION_KIND,\n aliases: [\"google_slides_presentation\"],\n label: \"Google Slides presentation\",\n description: \"Create a blank Google Slides presentation.\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"out\" }],\n sideEffects: \"unsafe-to-replay\",\n outputShape: GOOGLE_SLIDES_PRESENTATION_OUTPUT,\n configSchema: [\n {\n \"type\": \"text\",\n \"key\": \"title\",\n \"label\": \"Title\",\n \"required\": true,\n \"description\": \"The title of the new blank presentation.\"\n }\n ],\n defaultConfig: {\n \"mode\": \"auto\"\n },\n renderBody: ({ config }) =>\n summarize(GOOGLE_SLIDES_PRESENTATION_META, config as Record<string, unknown>, \"create a blank presentation\"),\n});\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/manifest.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/manifest.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- google_slides\n */\n\n/**\n * Google Slides's node kinds for fancy-flow.\n *\n * Install this on every host. The TypeScript executors live in the js\n * package's `./flow` subpath; PHP and Python hosts run their own and need only\n * this.\n */\n\nexport * from \"./service.js\";\nexport * from \"./kinds/presentation-create.js\";\n\nimport type { NodeKindDefinition } from \"@particle-academy/fancy-flow/engine\";\nimport { googleSlidesPresentationKind } from \"./kinds/presentation-create.js\";\n\n/** Every Google Slides kind, for a host that registers the lot. */\nexport const GOOGLE_SLIDES_KINDS: NodeKindDefinition[] = [\n googleSlidesPresentationKind,\n];\n"]}
1
+ {"version":3,"sources":["../src/service.ts","../src/kinds/presentation-create.ts","../src/kinds/presentation-get.ts","../src/index.ts"],"names":["defineConnectorKind","summarize"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/manifest.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/manifest.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- google_slides\n */\n\n/**\n * Google Slides's identity on the authoring surface, shared by every Google\n * Slides node.\n *\n * This file must import nothing from the js package: a PHP or Python project\n * installs the ui package and never that one, and the import would be a\n * dangling module the moment it did.\n *\n * ## The sandbox trap\n *\n * Google has no sandbox for Slides. A test presentation is a real one in a\n * real Drive, so every create is real -- use the faker while developing and\n * clean up any live test presentations.\n */\n\nimport type { ConnectorDomain, ConnectorMeta } from \"@particle-academy/fancy-flow/connectors\";\n\n/**\n * The connector API version this package was GENERATED against.\n *\n * A literal, never imported — an imported constant lets an upgrade rewrite the\n * very claim it exists to detect.\n */\nexport const CONNECTOR_API_VERSION = 1;\n\n/** The parts of a connector's identity that belong to the SERVICE, not the node. */\nexport const GOOGLE_SLIDES_SERVICE = {\n service: \"google_slides\",\n serviceTitle: \"Google Slides\",\n domain: \"productivity\",\n sandbox: \"none\",\n} as const satisfies Pick<ConnectorMeta, \"service\" | \"serviceTitle\" | \"domain\" | \"sandbox\">;\n\n/**\n * Every connector domain weaver knows, pinned against fancy-flow's union.\n *\n * A closed set copied into three codebases stays correct only while something\n * MAKES it: this line fails to compile the moment weaver carries a value\n * fancy-flow does not, including the values no provider uses yet.\n */\nconst WEAVER_DOMAINS: readonly ConnectorDomain[] = [\n \"payments\",\n \"commerce\",\n \"messaging\",\n \"email\",\n \"crm\",\n \"support\",\n \"storage\",\n \"calendar\",\n \"productivity\",\n \"database\",\n \"devtools\",\n \"analytics\",\n \"marketing\",\n \"ai\",\n \"forms\",\n \"hr\",\n \"geo\"\n];\nvoid WEAVER_DOMAINS;\n\n/** The credentials a Google Slides connection holds. */\nexport const GOOGLE_SLIDES_CREDENTIALS = [\n {\n \"key\": \"clientId\",\n \"label\": \"OAuth client ID\",\n \"scope\": \"provider\",\n \"secret\": false,\n \"help\": \"From Google Cloud Console -> APIs & Services -> Credentials. ONE value for the whole installation, not per connected account.\"\n },\n {\n \"key\": \"clientSecret\",\n \"label\": \"OAuth client secret\",\n \"scope\": \"provider\",\n \"secret\": true,\n \"help\": \"The client secret for the same OAuth app. One value for the whole installation.\"\n },\n {\n \"key\": \"accessToken\",\n \"label\": \"Access token\",\n \"scope\": \"account\",\n \"secret\": true,\n \"help\": \"Per connected Google account, and it expires after ONE HOUR. The host refreshes it with the refresh token.\"\n },\n {\n \"key\": \"refreshToken\",\n \"label\": \"Refresh token\",\n \"scope\": \"account\",\n \"secret\": true,\n \"help\": \"Per connected Google account. Google issues one only when the consent request asks for offline access; without it the connection dies within the hour.\"\n }\n] as const;\n\n/**\n * The OAuth2 exchange Google Slides requires — DECLARED here, performed by the\n * host.\n *\n * A consent screen needs a browser, a redirect URI and somewhere to persist\n * the result, and all three belong to the host; a package that ran the dance\n * itself would have to own a web server. So this says precisely enough for a\n * host to do it.\n *\n * The access token lasts 3600 seconds. A host that never refreshes will work\n * all afternoon and be broken by morning, which is why the lifetime is stated\n * rather than left to be discovered.\n *\n * Its refresh tokens do NOT rotate: the same one is reusable, so a refresh may\n * safely be retried and may run concurrently. That is stated rather than\n * assumed because the opposite — a provider that spends the token and revokes\n * the grant on a replay — looks identical until it happens.\n */\nexport const GOOGLE_SLIDES_OAUTH = {\n \"flow\": \"authorization_code\",\n \"authorizeUrl\": \"https://accounts.google.com/o/oauth2/v2/auth\",\n \"tokenUrl\": \"https://oauth2.googleapis.com/token\",\n \"scopes\": [\n \"https://www.googleapis.com/auth/presentations\"\n ],\n \"accessTokenCredential\": \"accessToken\",\n \"refreshTokenCredential\": \"refreshToken\",\n \"refreshTokenRotates\": false,\n \"accessTokenTtlSeconds\": 3600\n} as const;\n\n/** Build a Google Slides node's connector metadata from the operation it performs. */\nexport function googleSlidesMeta(\n role: ConnectorMeta[\"role\"],\n operation: string,\n docs: string,\n): ConnectorMeta {\n return { ...GOOGLE_SLIDES_SERVICE, role, operation, docs };\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/presentation-create.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/presentation-create.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- google_slides\n */\n\n/**\n * Google Slides presentation — Create a blank Google Slides presentation.\n *\n * https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/create\n *\n * `unsafe-to-replay`.\n */\n\nimport type { NodeKindDefinition } from \"@particle-academy/fancy-flow/engine\";\nimport { defineConnectorKind, summarize, type OutputField } from \"@particle-academy/fancy-flow/connectors\";\nimport { googleSlidesMeta } from \"../service.js\";\n\nexport const GOOGLE_SLIDES_PRESENTATION_KIND = \"@particle-academy/google_slides_presentation\";\nexport const GOOGLE_SLIDES_PRESENTATION_OPERATION = \"presentation_create\";\n\nexport const GOOGLE_SLIDES_PRESENTATION_META = googleSlidesMeta(\"action\", \"create a blank presentation\", \"https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/create\");\n\n/**\n * What this node emits — the \"ingredients\" a downstream node can reference.\n *\n * fancy-flow reads `outputShape` off the kind and offers it in the variable\n * picker, so declaring it is the whole of the work: an author configuring the\n * next node picks `{{ $json.data.id }}` off a list instead of typing a path\n * and hoping.\n */\nexport const GOOGLE_SLIDES_PRESENTATION_OUTPUT: OutputField[] = [\n {\n \"path\": \"data.presentationId\",\n \"type\": \"string\",\n \"description\": \"The id of the created presentation.\"\n },\n {\n \"path\": \"data.title\",\n \"type\": \"string\",\n \"description\": \"The title Google stored.\"\n }\n];\n\nexport const googleSlidesPresentationKind: NodeKindDefinition = defineConnectorKind(GOOGLE_SLIDES_PRESENTATION_META, {\n name: GOOGLE_SLIDES_PRESENTATION_KIND,\n aliases: [\"google_slides_presentation\"],\n label: \"Google Slides presentation\",\n description: \"Create a blank Google Slides presentation.\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"out\" }],\n sideEffects: \"unsafe-to-replay\",\n outputShape: GOOGLE_SLIDES_PRESENTATION_OUTPUT,\n configSchema: [\n {\n \"type\": \"text\",\n \"key\": \"title\",\n \"label\": \"Title\",\n \"required\": true,\n \"description\": \"The title of the new blank presentation.\"\n }\n ],\n defaultConfig: {\n \"mode\": \"auto\"\n },\n renderBody: ({ config }) =>\n summarize(GOOGLE_SLIDES_PRESENTATION_META, config as Record<string, unknown>, \"create a blank presentation\"),\n});\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/presentation-get.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/presentation-get.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- google_slides\n */\n\n/**\n * Google Slides presentation — Read a presentation's slides and the objectId\n * of every element on them -- the prerequisite for targeting a specific shape\n * or placeholder with a future edit.\n *\n * https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/get\n */\n\nimport type { NodeKindDefinition } from \"@particle-academy/fancy-flow/engine\";\nimport { defineConnectorKind, summarize, type OutputField } from \"@particle-academy/fancy-flow/connectors\";\nimport { googleSlidesMeta } from \"../service.js\";\n\nexport const GOOGLE_SLIDES_PRESENTATION_GET_KIND = \"@particle-academy/google_slides_presentation_get\";\nexport const GOOGLE_SLIDES_PRESENTATION_GET_OPERATION = \"presentation_get\";\n\nexport const GOOGLE_SLIDES_PRESENTATION_GET_META = googleSlidesMeta(\"action\", \"read a presentation\", \"https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/get\");\n\n/**\n * What this node emits — the \"ingredients\" a downstream node can reference.\n *\n * fancy-flow reads `outputShape` off the kind and offers it in the variable\n * picker, so declaring it is the whole of the work: an author configuring the\n * next node picks `{{ $json.data.id }}` off a list instead of typing a path\n * and hoping.\n */\nexport const GOOGLE_SLIDES_PRESENTATION_GET_OUTPUT: OutputField[] = [\n {\n \"path\": \"data.presentationId\",\n \"type\": \"string\",\n \"description\": \"Echoes what was asked.\"\n },\n {\n \"path\": \"data.title\",\n \"type\": \"string\",\n \"description\": \"The presentation's title.\"\n },\n {\n \"path\": \"data.locale\",\n \"type\": \"string\",\n \"description\": \"BCP 47 language tag.\"\n },\n {\n \"path\": \"data.slides\",\n \"type\": \"array\",\n \"description\": \"One entry per slide, in order: objectId, and pageElements -- each with its own objectId and exactly one of shape/image/table/line/video/wordArt/sheetsChart/elementGroup/speakerSpotlight set, naming what kind of element it is. A placeholder shape's text (when it has one) lives at pageElements[].shape.text, published raw -- this connector does not flatten Slides' own rich-text run structure.\"\n },\n {\n \"path\": \"mode\",\n \"type\": \"string\",\n \"description\": \"Which estate this ran against. Google has no sandbox, so: fake or live.\"\n }\n];\n\nexport const googleSlidesPresentationGetKind: NodeKindDefinition = defineConnectorKind(GOOGLE_SLIDES_PRESENTATION_GET_META, {\n name: GOOGLE_SLIDES_PRESENTATION_GET_KIND,\n aliases: [\"google_slides_presentation_get\"],\n label: \"Google Slides presentation\",\n description: \"Read a presentation's slides and the objectId of every element on them -- the prerequisite for targeting a specific shape or placeholder with a future edit.\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"out\" }],\n sideEffects: \"none\",\n outputShape: GOOGLE_SLIDES_PRESENTATION_GET_OUTPUT,\n configSchema: [\n {\n \"type\": \"text\",\n \"key\": \"presentationId\",\n \"label\": \"Presentation ID\",\n \"required\": true,\n \"description\": \"From presentation_create's data.presentationId, or the id in the presentation's own URL.\"\n }\n ],\n defaultConfig: {\n \"mode\": \"auto\"\n },\n renderBody: ({ config }) =>\n summarize(GOOGLE_SLIDES_PRESENTATION_GET_META, config as Record<string, unknown>, \"read a presentation\"),\n});\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/manifest.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/manifest.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- google_slides\n */\n\n/**\n * Google Slides's node kinds for fancy-flow.\n *\n * Install this on every host. The TypeScript executors live in the js\n * package's `./flow` subpath; PHP and Python hosts run their own and need only\n * this.\n */\n\nexport * from \"./service.js\";\nexport * from \"./kinds/presentation-create.js\";\nexport * from \"./kinds/presentation-get.js\";\n\nimport type { NodeKindDefinition } from \"@particle-academy/fancy-flow/engine\";\nimport { googleSlidesPresentationKind } from \"./kinds/presentation-create.js\";\nimport { googleSlidesPresentationGetKind } from \"./kinds/presentation-get.js\";\n\n/** Every Google Slides kind, for a host that registers the lot. */\nexport const GOOGLE_SLIDES_KINDS: NodeKindDefinition[] = [\n googleSlidesPresentationKind,\n googleSlidesPresentationGetKind,\n];\n"]}
package/dist/index.d.cts CHANGED
@@ -112,6 +112,20 @@ declare const GOOGLE_SLIDES_PRESENTATION_META: _particle_academy_fancy_flow_conn
112
112
  declare const GOOGLE_SLIDES_PRESENTATION_OUTPUT: OutputField[];
113
113
  declare const googleSlidesPresentationKind: NodeKindDefinition;
114
114
 
115
+ declare const GOOGLE_SLIDES_PRESENTATION_GET_KIND = "@particle-academy/google_slides_presentation_get";
116
+ declare const GOOGLE_SLIDES_PRESENTATION_GET_OPERATION = "presentation_get";
117
+ declare const GOOGLE_SLIDES_PRESENTATION_GET_META: _particle_academy_fancy_flow_connectors.ConnectorMeta;
118
+ /**
119
+ * What this node emits — the "ingredients" a downstream node can reference.
120
+ *
121
+ * fancy-flow reads `outputShape` off the kind and offers it in the variable
122
+ * picker, so declaring it is the whole of the work: an author configuring the
123
+ * next node picks `{{ $json.data.id }}` off a list instead of typing a path
124
+ * and hoping.
125
+ */
126
+ declare const GOOGLE_SLIDES_PRESENTATION_GET_OUTPUT: OutputField[];
127
+ declare const googleSlidesPresentationGetKind: NodeKindDefinition;
128
+
115
129
  /**
116
130
  * GENERATED FILE — do not edit.
117
131
  *
@@ -133,4 +147,4 @@ declare const googleSlidesPresentationKind: NodeKindDefinition;
133
147
  /** Every Google Slides kind, for a host that registers the lot. */
134
148
  declare const GOOGLE_SLIDES_KINDS: NodeKindDefinition[];
135
149
 
136
- export { CONNECTOR_API_VERSION, GOOGLE_SLIDES_CREDENTIALS, GOOGLE_SLIDES_KINDS, GOOGLE_SLIDES_OAUTH, GOOGLE_SLIDES_PRESENTATION_KIND, GOOGLE_SLIDES_PRESENTATION_META, GOOGLE_SLIDES_PRESENTATION_OPERATION, GOOGLE_SLIDES_PRESENTATION_OUTPUT, GOOGLE_SLIDES_SERVICE, googleSlidesMeta, googleSlidesPresentationKind };
150
+ export { CONNECTOR_API_VERSION, GOOGLE_SLIDES_CREDENTIALS, GOOGLE_SLIDES_KINDS, GOOGLE_SLIDES_OAUTH, GOOGLE_SLIDES_PRESENTATION_GET_KIND, GOOGLE_SLIDES_PRESENTATION_GET_META, GOOGLE_SLIDES_PRESENTATION_GET_OPERATION, GOOGLE_SLIDES_PRESENTATION_GET_OUTPUT, GOOGLE_SLIDES_PRESENTATION_KIND, GOOGLE_SLIDES_PRESENTATION_META, GOOGLE_SLIDES_PRESENTATION_OPERATION, GOOGLE_SLIDES_PRESENTATION_OUTPUT, GOOGLE_SLIDES_SERVICE, googleSlidesMeta, googleSlidesPresentationGetKind, googleSlidesPresentationKind };
package/dist/index.d.ts CHANGED
@@ -112,6 +112,20 @@ declare const GOOGLE_SLIDES_PRESENTATION_META: _particle_academy_fancy_flow_conn
112
112
  declare const GOOGLE_SLIDES_PRESENTATION_OUTPUT: OutputField[];
113
113
  declare const googleSlidesPresentationKind: NodeKindDefinition;
114
114
 
115
+ declare const GOOGLE_SLIDES_PRESENTATION_GET_KIND = "@particle-academy/google_slides_presentation_get";
116
+ declare const GOOGLE_SLIDES_PRESENTATION_GET_OPERATION = "presentation_get";
117
+ declare const GOOGLE_SLIDES_PRESENTATION_GET_META: _particle_academy_fancy_flow_connectors.ConnectorMeta;
118
+ /**
119
+ * What this node emits — the "ingredients" a downstream node can reference.
120
+ *
121
+ * fancy-flow reads `outputShape` off the kind and offers it in the variable
122
+ * picker, so declaring it is the whole of the work: an author configuring the
123
+ * next node picks `{{ $json.data.id }}` off a list instead of typing a path
124
+ * and hoping.
125
+ */
126
+ declare const GOOGLE_SLIDES_PRESENTATION_GET_OUTPUT: OutputField[];
127
+ declare const googleSlidesPresentationGetKind: NodeKindDefinition;
128
+
115
129
  /**
116
130
  * GENERATED FILE — do not edit.
117
131
  *
@@ -133,4 +147,4 @@ declare const googleSlidesPresentationKind: NodeKindDefinition;
133
147
  /** Every Google Slides kind, for a host that registers the lot. */
134
148
  declare const GOOGLE_SLIDES_KINDS: NodeKindDefinition[];
135
149
 
136
- export { CONNECTOR_API_VERSION, GOOGLE_SLIDES_CREDENTIALS, GOOGLE_SLIDES_KINDS, GOOGLE_SLIDES_OAUTH, GOOGLE_SLIDES_PRESENTATION_KIND, GOOGLE_SLIDES_PRESENTATION_META, GOOGLE_SLIDES_PRESENTATION_OPERATION, GOOGLE_SLIDES_PRESENTATION_OUTPUT, GOOGLE_SLIDES_SERVICE, googleSlidesMeta, googleSlidesPresentationKind };
150
+ export { CONNECTOR_API_VERSION, GOOGLE_SLIDES_CREDENTIALS, GOOGLE_SLIDES_KINDS, GOOGLE_SLIDES_OAUTH, GOOGLE_SLIDES_PRESENTATION_GET_KIND, GOOGLE_SLIDES_PRESENTATION_GET_META, GOOGLE_SLIDES_PRESENTATION_GET_OPERATION, GOOGLE_SLIDES_PRESENTATION_GET_OUTPUT, GOOGLE_SLIDES_PRESENTATION_KIND, GOOGLE_SLIDES_PRESENTATION_META, GOOGLE_SLIDES_PRESENTATION_OPERATION, GOOGLE_SLIDES_PRESENTATION_OUTPUT, GOOGLE_SLIDES_SERVICE, googleSlidesMeta, googleSlidesPresentationGetKind, googleSlidesPresentationKind };
package/dist/index.js CHANGED
@@ -91,12 +91,66 @@ var googleSlidesPresentationKind = defineConnectorKind(GOOGLE_SLIDES_PRESENTATIO
91
91
  },
92
92
  renderBody: ({ config }) => summarize(GOOGLE_SLIDES_PRESENTATION_META, config, "create a blank presentation")
93
93
  });
94
+ var GOOGLE_SLIDES_PRESENTATION_GET_KIND = "@particle-academy/google_slides_presentation_get";
95
+ var GOOGLE_SLIDES_PRESENTATION_GET_OPERATION = "presentation_get";
96
+ var GOOGLE_SLIDES_PRESENTATION_GET_META = googleSlidesMeta("action", "read a presentation", "https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/get");
97
+ var GOOGLE_SLIDES_PRESENTATION_GET_OUTPUT = [
98
+ {
99
+ "path": "data.presentationId",
100
+ "type": "string",
101
+ "description": "Echoes what was asked."
102
+ },
103
+ {
104
+ "path": "data.title",
105
+ "type": "string",
106
+ "description": "The presentation's title."
107
+ },
108
+ {
109
+ "path": "data.locale",
110
+ "type": "string",
111
+ "description": "BCP 47 language tag."
112
+ },
113
+ {
114
+ "path": "data.slides",
115
+ "type": "array",
116
+ "description": "One entry per slide, in order: objectId, and pageElements -- each with its own objectId and exactly one of shape/image/table/line/video/wordArt/sheetsChart/elementGroup/speakerSpotlight set, naming what kind of element it is. A placeholder shape's text (when it has one) lives at pageElements[].shape.text, published raw -- this connector does not flatten Slides' own rich-text run structure."
117
+ },
118
+ {
119
+ "path": "mode",
120
+ "type": "string",
121
+ "description": "Which estate this ran against. Google has no sandbox, so: fake or live."
122
+ }
123
+ ];
124
+ var googleSlidesPresentationGetKind = defineConnectorKind(GOOGLE_SLIDES_PRESENTATION_GET_META, {
125
+ name: GOOGLE_SLIDES_PRESENTATION_GET_KIND,
126
+ aliases: ["google_slides_presentation_get"],
127
+ label: "Google Slides presentation",
128
+ description: "Read a presentation's slides and the objectId of every element on them -- the prerequisite for targeting a specific shape or placeholder with a future edit.",
129
+ inputs: [{ id: "in" }],
130
+ outputs: [{ id: "out" }],
131
+ sideEffects: "none",
132
+ outputShape: GOOGLE_SLIDES_PRESENTATION_GET_OUTPUT,
133
+ configSchema: [
134
+ {
135
+ "type": "text",
136
+ "key": "presentationId",
137
+ "label": "Presentation ID",
138
+ "required": true,
139
+ "description": "From presentation_create's data.presentationId, or the id in the presentation's own URL."
140
+ }
141
+ ],
142
+ defaultConfig: {
143
+ "mode": "auto"
144
+ },
145
+ renderBody: ({ config }) => summarize(GOOGLE_SLIDES_PRESENTATION_GET_META, config, "read a presentation")
146
+ });
94
147
 
95
148
  // src/index.ts
96
149
  var GOOGLE_SLIDES_KINDS = [
97
- googleSlidesPresentationKind
150
+ googleSlidesPresentationKind,
151
+ googleSlidesPresentationGetKind
98
152
  ];
99
153
 
100
- export { CONNECTOR_API_VERSION, GOOGLE_SLIDES_CREDENTIALS, GOOGLE_SLIDES_KINDS, GOOGLE_SLIDES_OAUTH, GOOGLE_SLIDES_PRESENTATION_KIND, GOOGLE_SLIDES_PRESENTATION_META, GOOGLE_SLIDES_PRESENTATION_OPERATION, GOOGLE_SLIDES_PRESENTATION_OUTPUT, GOOGLE_SLIDES_SERVICE, googleSlidesMeta, googleSlidesPresentationKind };
154
+ export { CONNECTOR_API_VERSION, GOOGLE_SLIDES_CREDENTIALS, GOOGLE_SLIDES_KINDS, GOOGLE_SLIDES_OAUTH, GOOGLE_SLIDES_PRESENTATION_GET_KIND, GOOGLE_SLIDES_PRESENTATION_GET_META, GOOGLE_SLIDES_PRESENTATION_GET_OPERATION, GOOGLE_SLIDES_PRESENTATION_GET_OUTPUT, GOOGLE_SLIDES_PRESENTATION_KIND, GOOGLE_SLIDES_PRESENTATION_META, GOOGLE_SLIDES_PRESENTATION_OPERATION, GOOGLE_SLIDES_PRESENTATION_OUTPUT, GOOGLE_SLIDES_SERVICE, googleSlidesMeta, googleSlidesPresentationGetKind, googleSlidesPresentationKind };
101
155
  //# sourceMappingURL=index.js.map
102
156
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/service.ts","../src/kinds/presentation-create.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/manifest.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/manifest.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- google_slides\n */\n\n/**\n * Google Slides's identity on the authoring surface, shared by every Google\n * Slides node.\n *\n * This file must import nothing from the js package: a PHP or Python project\n * installs the ui package and never that one, and the import would be a\n * dangling module the moment it did.\n *\n * ## The sandbox trap\n *\n * Google has no sandbox for Slides. A test presentation is a real one in a\n * real Drive, so every create is real -- use the faker while developing and\n * clean up any live test presentations.\n */\n\nimport type { ConnectorDomain, ConnectorMeta } from \"@particle-academy/fancy-flow/connectors\";\n\n/**\n * The connector API version this package was GENERATED against.\n *\n * A literal, never imported — an imported constant lets an upgrade rewrite the\n * very claim it exists to detect.\n */\nexport const CONNECTOR_API_VERSION = 1;\n\n/** The parts of a connector's identity that belong to the SERVICE, not the node. */\nexport const GOOGLE_SLIDES_SERVICE = {\n service: \"google_slides\",\n serviceTitle: \"Google Slides\",\n domain: \"productivity\",\n sandbox: \"none\",\n} as const satisfies Pick<ConnectorMeta, \"service\" | \"serviceTitle\" | \"domain\" | \"sandbox\">;\n\n/**\n * Every connector domain weaver knows, pinned against fancy-flow's union.\n *\n * A closed set copied into three codebases stays correct only while something\n * MAKES it: this line fails to compile the moment weaver carries a value\n * fancy-flow does not, including the values no provider uses yet.\n */\nconst WEAVER_DOMAINS: readonly ConnectorDomain[] = [\n \"payments\",\n \"commerce\",\n \"messaging\",\n \"email\",\n \"crm\",\n \"support\",\n \"storage\",\n \"calendar\",\n \"productivity\",\n \"database\",\n \"devtools\",\n \"analytics\",\n \"marketing\",\n \"ai\",\n \"forms\",\n \"hr\",\n \"geo\"\n];\nvoid WEAVER_DOMAINS;\n\n/** The credentials a Google Slides connection holds. */\nexport const GOOGLE_SLIDES_CREDENTIALS = [\n {\n \"key\": \"clientId\",\n \"label\": \"OAuth client ID\",\n \"scope\": \"provider\",\n \"secret\": false,\n \"help\": \"From Google Cloud Console -> APIs & Services -> Credentials. ONE value for the whole installation, not per connected account.\"\n },\n {\n \"key\": \"clientSecret\",\n \"label\": \"OAuth client secret\",\n \"scope\": \"provider\",\n \"secret\": true,\n \"help\": \"The client secret for the same OAuth app. One value for the whole installation.\"\n },\n {\n \"key\": \"accessToken\",\n \"label\": \"Access token\",\n \"scope\": \"account\",\n \"secret\": true,\n \"help\": \"Per connected Google account, and it expires after ONE HOUR. The host refreshes it with the refresh token.\"\n },\n {\n \"key\": \"refreshToken\",\n \"label\": \"Refresh token\",\n \"scope\": \"account\",\n \"secret\": true,\n \"help\": \"Per connected Google account. Google issues one only when the consent request asks for offline access; without it the connection dies within the hour.\"\n }\n] as const;\n\n/**\n * The OAuth2 exchange Google Slides requires — DECLARED here, performed by the\n * host.\n *\n * A consent screen needs a browser, a redirect URI and somewhere to persist\n * the result, and all three belong to the host; a package that ran the dance\n * itself would have to own a web server. So this says precisely enough for a\n * host to do it.\n *\n * The access token lasts 3600 seconds. A host that never refreshes will work\n * all afternoon and be broken by morning, which is why the lifetime is stated\n * rather than left to be discovered.\n *\n * Its refresh tokens do NOT rotate: the same one is reusable, so a refresh may\n * safely be retried and may run concurrently. That is stated rather than\n * assumed because the opposite — a provider that spends the token and revokes\n * the grant on a replay — looks identical until it happens.\n */\nexport const GOOGLE_SLIDES_OAUTH = {\n \"flow\": \"authorization_code\",\n \"authorizeUrl\": \"https://accounts.google.com/o/oauth2/v2/auth\",\n \"tokenUrl\": \"https://oauth2.googleapis.com/token\",\n \"scopes\": [\n \"https://www.googleapis.com/auth/presentations\"\n ],\n \"accessTokenCredential\": \"accessToken\",\n \"refreshTokenCredential\": \"refreshToken\",\n \"refreshTokenRotates\": false,\n \"accessTokenTtlSeconds\": 3600\n} as const;\n\n/** Build a Google Slides node's connector metadata from the operation it performs. */\nexport function googleSlidesMeta(\n role: ConnectorMeta[\"role\"],\n operation: string,\n docs: string,\n): ConnectorMeta {\n return { ...GOOGLE_SLIDES_SERVICE, role, operation, docs };\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/presentation-create.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/presentation-create.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- google_slides\n */\n\n/**\n * Google Slides presentation — Create a blank Google Slides presentation.\n *\n * https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/create\n *\n * `unsafe-to-replay`.\n */\n\nimport type { NodeKindDefinition } from \"@particle-academy/fancy-flow/engine\";\nimport { defineConnectorKind, summarize, type OutputField } from \"@particle-academy/fancy-flow/connectors\";\nimport { googleSlidesMeta } from \"../service.js\";\n\nexport const GOOGLE_SLIDES_PRESENTATION_KIND = \"@particle-academy/google_slides_presentation\";\nexport const GOOGLE_SLIDES_PRESENTATION_OPERATION = \"presentation_create\";\n\nexport const GOOGLE_SLIDES_PRESENTATION_META = googleSlidesMeta(\"action\", \"create a blank presentation\", \"https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/create\");\n\n/**\n * What this node emits — the \"ingredients\" a downstream node can reference.\n *\n * fancy-flow reads `outputShape` off the kind and offers it in the variable\n * picker, so declaring it is the whole of the work: an author configuring the\n * next node picks `{{ $json.data.id }}` off a list instead of typing a path\n * and hoping.\n */\nexport const GOOGLE_SLIDES_PRESENTATION_OUTPUT: OutputField[] = [\n {\n \"path\": \"data.presentationId\",\n \"type\": \"string\",\n \"description\": \"The id of the created presentation.\"\n },\n {\n \"path\": \"data.title\",\n \"type\": \"string\",\n \"description\": \"The title Google stored.\"\n }\n];\n\nexport const googleSlidesPresentationKind: NodeKindDefinition = defineConnectorKind(GOOGLE_SLIDES_PRESENTATION_META, {\n name: GOOGLE_SLIDES_PRESENTATION_KIND,\n aliases: [\"google_slides_presentation\"],\n label: \"Google Slides presentation\",\n description: \"Create a blank Google Slides presentation.\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"out\" }],\n sideEffects: \"unsafe-to-replay\",\n outputShape: GOOGLE_SLIDES_PRESENTATION_OUTPUT,\n configSchema: [\n {\n \"type\": \"text\",\n \"key\": \"title\",\n \"label\": \"Title\",\n \"required\": true,\n \"description\": \"The title of the new blank presentation.\"\n }\n ],\n defaultConfig: {\n \"mode\": \"auto\"\n },\n renderBody: ({ config }) =>\n summarize(GOOGLE_SLIDES_PRESENTATION_META, config as Record<string, unknown>, \"create a blank presentation\"),\n});\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/manifest.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/manifest.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- google_slides\n */\n\n/**\n * Google Slides's node kinds for fancy-flow.\n *\n * Install this on every host. The TypeScript executors live in the js\n * package's `./flow` subpath; PHP and Python hosts run their own and need only\n * this.\n */\n\nexport * from \"./service.js\";\nexport * from \"./kinds/presentation-create.js\";\n\nimport type { NodeKindDefinition } from \"@particle-academy/fancy-flow/engine\";\nimport { googleSlidesPresentationKind } from \"./kinds/presentation-create.js\";\n\n/** Every Google Slides kind, for a host that registers the lot. */\nexport const GOOGLE_SLIDES_KINDS: NodeKindDefinition[] = [\n googleSlidesPresentationKind,\n];\n"]}
1
+ {"version":3,"sources":["../src/service.ts","../src/kinds/presentation-create.ts","../src/kinds/presentation-get.ts","../src/index.ts"],"names":["defineConnectorKind","summarize"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/manifest.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/manifest.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- google_slides\n */\n\n/**\n * Google Slides's identity on the authoring surface, shared by every Google\n * Slides node.\n *\n * This file must import nothing from the js package: a PHP or Python project\n * installs the ui package and never that one, and the import would be a\n * dangling module the moment it did.\n *\n * ## The sandbox trap\n *\n * Google has no sandbox for Slides. A test presentation is a real one in a\n * real Drive, so every create is real -- use the faker while developing and\n * clean up any live test presentations.\n */\n\nimport type { ConnectorDomain, ConnectorMeta } from \"@particle-academy/fancy-flow/connectors\";\n\n/**\n * The connector API version this package was GENERATED against.\n *\n * A literal, never imported — an imported constant lets an upgrade rewrite the\n * very claim it exists to detect.\n */\nexport const CONNECTOR_API_VERSION = 1;\n\n/** The parts of a connector's identity that belong to the SERVICE, not the node. */\nexport const GOOGLE_SLIDES_SERVICE = {\n service: \"google_slides\",\n serviceTitle: \"Google Slides\",\n domain: \"productivity\",\n sandbox: \"none\",\n} as const satisfies Pick<ConnectorMeta, \"service\" | \"serviceTitle\" | \"domain\" | \"sandbox\">;\n\n/**\n * Every connector domain weaver knows, pinned against fancy-flow's union.\n *\n * A closed set copied into three codebases stays correct only while something\n * MAKES it: this line fails to compile the moment weaver carries a value\n * fancy-flow does not, including the values no provider uses yet.\n */\nconst WEAVER_DOMAINS: readonly ConnectorDomain[] = [\n \"payments\",\n \"commerce\",\n \"messaging\",\n \"email\",\n \"crm\",\n \"support\",\n \"storage\",\n \"calendar\",\n \"productivity\",\n \"database\",\n \"devtools\",\n \"analytics\",\n \"marketing\",\n \"ai\",\n \"forms\",\n \"hr\",\n \"geo\"\n];\nvoid WEAVER_DOMAINS;\n\n/** The credentials a Google Slides connection holds. */\nexport const GOOGLE_SLIDES_CREDENTIALS = [\n {\n \"key\": \"clientId\",\n \"label\": \"OAuth client ID\",\n \"scope\": \"provider\",\n \"secret\": false,\n \"help\": \"From Google Cloud Console -> APIs & Services -> Credentials. ONE value for the whole installation, not per connected account.\"\n },\n {\n \"key\": \"clientSecret\",\n \"label\": \"OAuth client secret\",\n \"scope\": \"provider\",\n \"secret\": true,\n \"help\": \"The client secret for the same OAuth app. One value for the whole installation.\"\n },\n {\n \"key\": \"accessToken\",\n \"label\": \"Access token\",\n \"scope\": \"account\",\n \"secret\": true,\n \"help\": \"Per connected Google account, and it expires after ONE HOUR. The host refreshes it with the refresh token.\"\n },\n {\n \"key\": \"refreshToken\",\n \"label\": \"Refresh token\",\n \"scope\": \"account\",\n \"secret\": true,\n \"help\": \"Per connected Google account. Google issues one only when the consent request asks for offline access; without it the connection dies within the hour.\"\n }\n] as const;\n\n/**\n * The OAuth2 exchange Google Slides requires — DECLARED here, performed by the\n * host.\n *\n * A consent screen needs a browser, a redirect URI and somewhere to persist\n * the result, and all three belong to the host; a package that ran the dance\n * itself would have to own a web server. So this says precisely enough for a\n * host to do it.\n *\n * The access token lasts 3600 seconds. A host that never refreshes will work\n * all afternoon and be broken by morning, which is why the lifetime is stated\n * rather than left to be discovered.\n *\n * Its refresh tokens do NOT rotate: the same one is reusable, so a refresh may\n * safely be retried and may run concurrently. That is stated rather than\n * assumed because the opposite — a provider that spends the token and revokes\n * the grant on a replay — looks identical until it happens.\n */\nexport const GOOGLE_SLIDES_OAUTH = {\n \"flow\": \"authorization_code\",\n \"authorizeUrl\": \"https://accounts.google.com/o/oauth2/v2/auth\",\n \"tokenUrl\": \"https://oauth2.googleapis.com/token\",\n \"scopes\": [\n \"https://www.googleapis.com/auth/presentations\"\n ],\n \"accessTokenCredential\": \"accessToken\",\n \"refreshTokenCredential\": \"refreshToken\",\n \"refreshTokenRotates\": false,\n \"accessTokenTtlSeconds\": 3600\n} as const;\n\n/** Build a Google Slides node's connector metadata from the operation it performs. */\nexport function googleSlidesMeta(\n role: ConnectorMeta[\"role\"],\n operation: string,\n docs: string,\n): ConnectorMeta {\n return { ...GOOGLE_SLIDES_SERVICE, role, operation, docs };\n}\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/presentation-create.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/presentation-create.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- google_slides\n */\n\n/**\n * Google Slides presentation — Create a blank Google Slides presentation.\n *\n * https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/create\n *\n * `unsafe-to-replay`.\n */\n\nimport type { NodeKindDefinition } from \"@particle-academy/fancy-flow/engine\";\nimport { defineConnectorKind, summarize, type OutputField } from \"@particle-academy/fancy-flow/connectors\";\nimport { googleSlidesMeta } from \"../service.js\";\n\nexport const GOOGLE_SLIDES_PRESENTATION_KIND = \"@particle-academy/google_slides_presentation\";\nexport const GOOGLE_SLIDES_PRESENTATION_OPERATION = \"presentation_create\";\n\nexport const GOOGLE_SLIDES_PRESENTATION_META = googleSlidesMeta(\"action\", \"create a blank presentation\", \"https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/create\");\n\n/**\n * What this node emits — the \"ingredients\" a downstream node can reference.\n *\n * fancy-flow reads `outputShape` off the kind and offers it in the variable\n * picker, so declaring it is the whole of the work: an author configuring the\n * next node picks `{{ $json.data.id }}` off a list instead of typing a path\n * and hoping.\n */\nexport const GOOGLE_SLIDES_PRESENTATION_OUTPUT: OutputField[] = [\n {\n \"path\": \"data.presentationId\",\n \"type\": \"string\",\n \"description\": \"The id of the created presentation.\"\n },\n {\n \"path\": \"data.title\",\n \"type\": \"string\",\n \"description\": \"The title Google stored.\"\n }\n];\n\nexport const googleSlidesPresentationKind: NodeKindDefinition = defineConnectorKind(GOOGLE_SLIDES_PRESENTATION_META, {\n name: GOOGLE_SLIDES_PRESENTATION_KIND,\n aliases: [\"google_slides_presentation\"],\n label: \"Google Slides presentation\",\n description: \"Create a blank Google Slides presentation.\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"out\" }],\n sideEffects: \"unsafe-to-replay\",\n outputShape: GOOGLE_SLIDES_PRESENTATION_OUTPUT,\n configSchema: [\n {\n \"type\": \"text\",\n \"key\": \"title\",\n \"label\": \"Title\",\n \"required\": true,\n \"description\": \"The title of the new blank presentation.\"\n }\n ],\n defaultConfig: {\n \"mode\": \"auto\"\n },\n renderBody: ({ config }) =>\n summarize(GOOGLE_SLIDES_PRESENTATION_META, config as Record<string, unknown>, \"create a blank presentation\"),\n});\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/actions/presentation-get.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/actions/presentation-get.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- google_slides\n */\n\n/**\n * Google Slides presentation — Read a presentation's slides and the objectId\n * of every element on them -- the prerequisite for targeting a specific shape\n * or placeholder with a future edit.\n *\n * https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/get\n */\n\nimport type { NodeKindDefinition } from \"@particle-academy/fancy-flow/engine\";\nimport { defineConnectorKind, summarize, type OutputField } from \"@particle-academy/fancy-flow/connectors\";\nimport { googleSlidesMeta } from \"../service.js\";\n\nexport const GOOGLE_SLIDES_PRESENTATION_GET_KIND = \"@particle-academy/google_slides_presentation_get\";\nexport const GOOGLE_SLIDES_PRESENTATION_GET_OPERATION = \"presentation_get\";\n\nexport const GOOGLE_SLIDES_PRESENTATION_GET_META = googleSlidesMeta(\"action\", \"read a presentation\", \"https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/get\");\n\n/**\n * What this node emits — the \"ingredients\" a downstream node can reference.\n *\n * fancy-flow reads `outputShape` off the kind and offers it in the variable\n * picker, so declaring it is the whole of the work: an author configuring the\n * next node picks `{{ $json.data.id }}` off a list instead of typing a path\n * and hoping.\n */\nexport const GOOGLE_SLIDES_PRESENTATION_GET_OUTPUT: OutputField[] = [\n {\n \"path\": \"data.presentationId\",\n \"type\": \"string\",\n \"description\": \"Echoes what was asked.\"\n },\n {\n \"path\": \"data.title\",\n \"type\": \"string\",\n \"description\": \"The presentation's title.\"\n },\n {\n \"path\": \"data.locale\",\n \"type\": \"string\",\n \"description\": \"BCP 47 language tag.\"\n },\n {\n \"path\": \"data.slides\",\n \"type\": \"array\",\n \"description\": \"One entry per slide, in order: objectId, and pageElements -- each with its own objectId and exactly one of shape/image/table/line/video/wordArt/sheetsChart/elementGroup/speakerSpotlight set, naming what kind of element it is. A placeholder shape's text (when it has one) lives at pageElements[].shape.text, published raw -- this connector does not flatten Slides' own rich-text run structure.\"\n },\n {\n \"path\": \"mode\",\n \"type\": \"string\",\n \"description\": \"Which estate this ran against. Google has no sandbox, so: fake or live.\"\n }\n];\n\nexport const googleSlidesPresentationGetKind: NodeKindDefinition = defineConnectorKind(GOOGLE_SLIDES_PRESENTATION_GET_META, {\n name: GOOGLE_SLIDES_PRESENTATION_GET_KIND,\n aliases: [\"google_slides_presentation_get\"],\n label: \"Google Slides presentation\",\n description: \"Read a presentation's slides and the objectId of every element on them -- the prerequisite for targeting a specific shape or placeholder with a future edit.\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"out\" }],\n sideEffects: \"none\",\n outputShape: GOOGLE_SLIDES_PRESENTATION_GET_OUTPUT,\n configSchema: [\n {\n \"type\": \"text\",\n \"key\": \"presentationId\",\n \"label\": \"Presentation ID\",\n \"required\": true,\n \"description\": \"From presentation_create's data.presentationId, or the id in the presentation's own URL.\"\n }\n ],\n defaultConfig: {\n \"mode\": \"auto\"\n },\n renderBody: ({ config }) =>\n summarize(GOOGLE_SLIDES_PRESENTATION_GET_META, config as Record<string, unknown>, \"read a presentation\"),\n});\n","/**\n * GENERATED FILE — do not edit.\n *\n * Emitted from provider/manifest.json by weaver's generator.\n * A hand-edit here is destroyed by the next protocol sync, which is worse than\n * being rejected, because it works until it silently does not. Fix\n * provider/manifest.json (or weaver's template/) and regenerate:\n *\n * npm run provider -- google_slides\n */\n\n/**\n * Google Slides's node kinds for fancy-flow.\n *\n * Install this on every host. The TypeScript executors live in the js\n * package's `./flow` subpath; PHP and Python hosts run their own and need only\n * this.\n */\n\nexport * from \"./service.js\";\nexport * from \"./kinds/presentation-create.js\";\nexport * from \"./kinds/presentation-get.js\";\n\nimport type { NodeKindDefinition } from \"@particle-academy/fancy-flow/engine\";\nimport { googleSlidesPresentationKind } from \"./kinds/presentation-create.js\";\nimport { googleSlidesPresentationGetKind } from \"./kinds/presentation-get.js\";\n\n/** Every Google Slides kind, for a host that registers the lot. */\nexport const GOOGLE_SLIDES_KINDS: NodeKindDefinition[] = [\n googleSlidesPresentationKind,\n googleSlidesPresentationGetKind,\n];\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@particle-academy/google-slides-ui",
3
- "version": "0.3.4",
3
+ "version": "0.5.0",
4
4
  "description": "Google Slides's authoring surface for fancy-flow — the node kinds, their config schemas and their declared output shapes. React on every host; carries no executor.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -28,6 +28,7 @@
28
28
  },
29
29
  "files": [
30
30
  "dist",
31
+ "art",
31
32
  "README.md",
32
33
  "CHANGELOG.md",
33
34
  "LICENSE"