@plitzi/sdk-server 0.33.2 → 0.34.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.
Files changed (274) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +283 -8
  3. package/dist/actions.d.ts +62 -0
  4. package/dist/actions.js +12 -0
  5. package/dist/adapters/cloudAdapters.d.ts +72 -0
  6. package/dist/adapters/cloudAdapters.js +303 -0
  7. package/dist/adapters/space/index.d.ts +93 -0
  8. package/dist/adapters/space/index.js +122 -0
  9. package/dist/adapters/space/resolvers.d.ts +69 -0
  10. package/dist/adapters/space/resolvers.js +79 -0
  11. package/dist/adapters/space/space.test.d.ts +1 -0
  12. package/dist/adapters/space/types.d.ts +64 -0
  13. package/dist/adapters/space/types.js +41 -0
  14. package/dist/auth.d.ts +50 -0
  15. package/dist/auth.js +19 -0
  16. package/dist/core/auth/api.d.ts +400 -11
  17. package/dist/core/auth/api.js +1044 -50
  18. package/dist/core/auth/createAuth.d.ts +135 -30
  19. package/dist/core/auth/createAuth.js +96 -24
  20. package/dist/core/auth/credentials.d.ts +9 -3
  21. package/dist/core/auth/credentials.js +10 -4
  22. package/dist/core/auth/csrf.d.ts +89 -0
  23. package/dist/core/auth/csrf.js +234 -0
  24. package/dist/core/auth/csrf.test.d.ts +1 -0
  25. package/dist/core/auth/identity.d.ts +6 -0
  26. package/dist/core/auth/identity.js +37 -8
  27. package/dist/core/auth/lifecycle.test.d.ts +1 -0
  28. package/dist/core/auth/oauth/index.d.ts +8 -0
  29. package/dist/core/auth/oauth/index.js +13 -15
  30. package/dist/core/auth/passwords.d.ts +15 -0
  31. package/dist/core/auth/passwords.js +32 -0
  32. package/dist/core/auth/redirects.d.ts +18 -0
  33. package/dist/core/auth/redirects.js +31 -0
  34. package/dist/core/auth/redirects.test.d.ts +1 -0
  35. package/dist/core/auth/routes.d.ts +4 -2
  36. package/dist/core/auth/routes.js +234 -9
  37. package/dist/core/auth/session.d.ts +11 -0
  38. package/dist/core/auth/session.js +1 -1
  39. package/dist/core/auth/spaceTokens.d.ts +38 -2
  40. package/dist/core/auth/spaceTokens.js +54 -2
  41. package/dist/core/auth/throttle.d.ts +5 -0
  42. package/dist/core/auth/throttle.js +81 -0
  43. package/dist/core/auth/throttle.test.d.ts +1 -0
  44. package/dist/core/auth/tokens.d.ts +83 -12
  45. package/dist/core/auth/tokens.js +51 -9
  46. package/dist/core/auth/totp.d.ts +48 -0
  47. package/dist/core/auth/totp.js +118 -0
  48. package/dist/core/auth/totp.test.d.ts +1 -0
  49. package/dist/core/createServer.d.ts +0 -6
  50. package/dist/core/createServer.js +35 -3
  51. package/dist/core/fontStore.d.ts +33 -0
  52. package/dist/core/fontStore.js +53 -0
  53. package/dist/core/fontStore.test.d.ts +1 -0
  54. package/dist/core/handlers/authMiddleware.js +1 -1
  55. package/dist/core/handlers/authRouteHandlers.d.ts +9 -1
  56. package/dist/core/handlers/authRouteHandlers.js +4 -3
  57. package/dist/core/handlers/csrfMiddleware.d.ts +20 -0
  58. package/dist/core/handlers/csrfMiddleware.js +32 -0
  59. package/dist/core/handlers/oauthRouteHandlers.d.ts +46 -0
  60. package/dist/core/handlers/oauthRouteHandlers.js +159 -0
  61. package/dist/core/handlers/socialRouteHandlers.d.ts +40 -0
  62. package/dist/core/handlers/socialRouteHandlers.js +129 -0
  63. package/dist/core/handlers/socialRouteHandlers.test.d.ts +1 -0
  64. package/dist/core/handlers/types.d.ts +22 -5
  65. package/dist/core/health.d.ts +11 -1
  66. package/dist/core/health.js +27 -3
  67. package/dist/core/http/dispatcher.d.ts +1 -1
  68. package/dist/core/http/dispatcher.js +20 -1
  69. package/dist/core/http/stages/authApi.js +1 -1
  70. package/dist/core/http/stages/fontAssets.d.ts +9 -0
  71. package/dist/core/http/stages/fontAssets.js +27 -0
  72. package/dist/core/http/stages/oauth.d.ts +19 -0
  73. package/dist/core/http/stages/oauth.js +118 -0
  74. package/dist/core/http/types.d.ts +12 -0
  75. package/dist/core/oauth/authorize.d.ts +22 -0
  76. package/dist/core/oauth/authorize.js +254 -0
  77. package/dist/core/oauth/authorize.test.d.ts +1 -0
  78. package/dist/core/oauth/challenge.d.ts +11 -0
  79. package/dist/core/oauth/challenge.js +33 -0
  80. package/dist/core/oauth/consentPage.d.ts +12 -0
  81. package/dist/core/oauth/consentPage.js +131 -0
  82. package/dist/core/oauth/metadata.d.ts +41 -0
  83. package/dist/core/oauth/metadata.js +71 -0
  84. package/dist/core/oauth/params.d.ts +5 -0
  85. package/dist/core/oauth/params.js +5 -0
  86. package/dist/core/oauth/pkce.d.ts +6 -0
  87. package/dist/core/oauth/pkce.js +15 -0
  88. package/dist/core/oauth/records.d.ts +72 -0
  89. package/dist/core/oauth/records.js +49 -0
  90. package/dist/core/oauth/register.d.ts +5 -0
  91. package/dist/core/oauth/register.js +55 -0
  92. package/dist/core/oauth/respond.d.ts +21 -0
  93. package/dist/core/oauth/respond.js +59 -0
  94. package/dist/core/oauth/token.d.ts +14 -0
  95. package/dist/core/oauth/token.js +130 -0
  96. package/dist/core/previewToken.d.ts +20 -0
  97. package/dist/core/previewToken.js +29 -1
  98. package/dist/core/server/pageServer.js +4 -1
  99. package/dist/core/services/action.d.ts +6 -4
  100. package/dist/core/services/action.js +103 -10
  101. package/dist/core/services/registry.js +2 -0
  102. package/dist/core/services/resolve.d.ts +8 -0
  103. package/dist/core/services/resolve.js +12 -1
  104. package/dist/core/staticFiles.js +1 -2
  105. package/dist/handlers.d.ts +7 -1
  106. package/dist/handlers.js +4 -1
  107. package/dist/helpers/buildResponseHelpers.d.ts +8 -0
  108. package/dist/helpers/buildResponseHelpers.js +9 -1
  109. package/dist/helpers/buildServerInfo.d.ts +8 -3
  110. package/dist/helpers/buildServerInfo.js +18 -14
  111. package/dist/helpers/cache/keys.d.ts +13 -0
  112. package/dist/helpers/cache/keys.js +12 -1
  113. package/dist/helpers/onAbort.d.ts +12 -0
  114. package/dist/helpers/onAbort.js +22 -0
  115. package/dist/helpers/onAbort.test.d.ts +1 -0
  116. package/dist/helpers/outboundGuard.d.ts +27 -0
  117. package/dist/helpers/outboundGuard.js +49 -0
  118. package/dist/helpers/outboundGuard.test.d.ts +1 -0
  119. package/dist/helpers/serverLog.d.ts +6 -3
  120. package/dist/helpers/serverLog.js +20 -3
  121. package/dist/index.d.ts +6 -0
  122. package/dist/index.js +9 -4
  123. package/dist/kernel.d.ts +5 -22
  124. package/dist/kernel.js +1 -14
  125. package/dist/modules/actions/{handler.js → connectorWrite.js} +5 -2
  126. package/dist/modules/actions/connectorWrite.test.d.ts +1 -0
  127. package/dist/modules/actions/index.d.ts +40 -0
  128. package/dist/modules/actions/index.js +46 -0
  129. package/dist/modules/actions/moduleFor.d.ts +3 -0
  130. package/dist/modules/actions/moduleFor.js +35 -0
  131. package/dist/modules/actions/moduleFor.test.d.ts +1 -0
  132. package/dist/modules/actions/runtime/check.d.ts +24 -0
  133. package/dist/modules/actions/runtime/check.js +111 -0
  134. package/dist/modules/actions/runtime/check.test.d.ts +1 -0
  135. package/dist/modules/actions/runtime/errors.d.ts +11 -0
  136. package/dist/modules/actions/runtime/errors.js +17 -0
  137. package/dist/modules/actions/runtime/guards.d.ts +126 -0
  138. package/dist/modules/actions/runtime/guards.js +246 -0
  139. package/dist/modules/actions/runtime/guards.test.d.ts +1 -0
  140. package/dist/modules/actions/runtime/kvStore.d.ts +27 -0
  141. package/dist/modules/actions/runtime/kvStore.js +41 -0
  142. package/dist/modules/actions/runtime/kvStore.test.d.ts +1 -0
  143. package/dist/modules/actions/runtime/limits.d.ts +11 -0
  144. package/dist/modules/actions/runtime/limits.js +35 -0
  145. package/dist/modules/actions/runtime/memoryKv.d.ts +2 -0
  146. package/dist/modules/actions/runtime/memoryKv.js +77 -0
  147. package/dist/modules/actions/runtime/namespaceKv.d.ts +9 -0
  148. package/dist/modules/actions/runtime/namespaceKv.js +19 -0
  149. package/dist/modules/actions/runtime/precheck.d.ts +27 -0
  150. package/dist/modules/actions/runtime/precheck.js +45 -0
  151. package/dist/modules/actions/runtime/renderResolver.d.ts +15 -0
  152. package/dist/modules/actions/runtime/renderResolver.js +130 -0
  153. package/dist/modules/actions/runtime/renderResolver.test.d.ts +1 -0
  154. package/dist/modules/actions/runtime/renderShare.d.ts +29 -0
  155. package/dist/modules/actions/runtime/renderShare.js +36 -0
  156. package/dist/modules/actions/runtime/renderShare.test.d.ts +1 -0
  157. package/dist/modules/actions/runtime/report.d.ts +14 -0
  158. package/dist/modules/actions/runtime/report.js +22 -0
  159. package/dist/modules/actions/runtime/runAction.d.ts +12 -0
  160. package/dist/modules/actions/runtime/runAction.js +405 -0
  161. package/dist/modules/actions/runtime/runAction.test.d.ts +1 -0
  162. package/dist/modules/actions/runtime/runLogger.d.ts +31 -0
  163. package/dist/modules/actions/runtime/runLogger.js +66 -0
  164. package/dist/modules/actions/runtime/runLogger.test.d.ts +1 -0
  165. package/dist/modules/actions/runtime/schedule.d.ts +35 -0
  166. package/dist/modules/actions/runtime/schedule.js +76 -0
  167. package/dist/modules/actions/runtime/schedule.test.d.ts +1 -0
  168. package/dist/modules/actions/runtime/scope.d.ts +40 -0
  169. package/dist/modules/actions/runtime/scope.js +103 -0
  170. package/dist/modules/actions/runtime/triggers.d.ts +12 -0
  171. package/dist/modules/actions/runtime/triggers.js +14 -0
  172. package/dist/modules/actions/taskCatalog.d.ts +26 -0
  173. package/dist/modules/actions/taskCatalog.js +24 -0
  174. package/dist/modules/actions/taskCatalog.test.d.ts +1 -0
  175. package/dist/modules/actions/tasks/auth.d.ts +2 -0
  176. package/dist/modules/actions/tasks/auth.js +40 -0
  177. package/dist/modules/actions/tasks/builtins.d.ts +8 -0
  178. package/dist/modules/actions/tasks/builtins.js +24 -0
  179. package/dist/modules/actions/tasks/connector.d.ts +2 -0
  180. package/dist/modules/actions/tasks/connector.js +141 -0
  181. package/dist/modules/actions/tasks/db.d.ts +2 -0
  182. package/dist/modules/actions/tasks/db.js +59 -0
  183. package/dist/modules/actions/tasks/db.test.d.ts +1 -0
  184. package/dist/modules/actions/tasks/flow.d.ts +3 -0
  185. package/dist/modules/actions/tasks/flow.js +109 -0
  186. package/dist/modules/actions/tasks/helpers.d.ts +16 -0
  187. package/dist/modules/actions/tasks/helpers.js +30 -0
  188. package/dist/modules/actions/tasks/http.d.ts +2 -0
  189. package/dist/modules/actions/tasks/http.js +111 -0
  190. package/dist/modules/actions/tasks/http.test.d.ts +1 -0
  191. package/dist/modules/actions/tasks/kv.d.ts +2 -0
  192. package/dist/modules/actions/tasks/kv.js +102 -0
  193. package/dist/modules/actions/tasks/kv.test.d.ts +1 -0
  194. package/dist/modules/actions/tasks/registry.d.ts +10 -0
  195. package/dist/modules/actions/tasks/registry.js +36 -0
  196. package/dist/modules/actions/tasks/transform.d.ts +2 -0
  197. package/dist/modules/actions/tasks/transform.js +34 -0
  198. package/dist/modules/actions/transport/callHandler.d.ts +24 -0
  199. package/dist/modules/actions/transport/callHandler.js +233 -0
  200. package/dist/modules/actions/transport/callHandler.test.d.ts +1 -0
  201. package/dist/modules/actions/transport/cancelHandler.d.ts +23 -0
  202. package/dist/modules/actions/transport/cancelHandler.js +23 -0
  203. package/dist/modules/actions/transport/catalogHandler.d.ts +18 -0
  204. package/dist/modules/actions/transport/catalogHandler.js +21 -0
  205. package/dist/modules/actions/transport/stream.d.ts +23 -0
  206. package/dist/modules/actions/transport/stream.js +100 -0
  207. package/dist/modules/actions/transport/verifySignature.d.ts +16 -0
  208. package/dist/modules/actions/transport/verifySignature.js +72 -0
  209. package/dist/modules/actions/transport/webhookHandler.d.ts +25 -0
  210. package/dist/modules/actions/transport/webhookHandler.js +206 -0
  211. package/dist/modules/actions/transport/webhookHandler.test.d.ts +1 -0
  212. package/dist/modules/actions/types.d.ts +234 -0
  213. package/dist/modules/connectors/engine.js +4 -1
  214. package/dist/modules/connectors/resolver.d.ts +10 -2
  215. package/dist/modules/connectors/resolver.js +8 -3
  216. package/dist/modules/mysql/accounts.d.ts +5 -0
  217. package/dist/modules/mysql/accounts.js +365 -0
  218. package/dist/modules/mysql/accounts.test.d.ts +1 -0
  219. package/dist/modules/mysql/admin.d.ts +58 -0
  220. package/dist/modules/mysql/admin.js +133 -0
  221. package/dist/modules/mysql/config.d.ts +82 -0
  222. package/dist/modules/mysql/config.js +30 -0
  223. package/dist/modules/mysql/identities.d.ts +35 -0
  224. package/dist/modules/mysql/identities.js +43 -0
  225. package/dist/modules/mysql/index.d.ts +67 -0
  226. package/dist/modules/mysql/index.js +62 -0
  227. package/dist/modules/mysql/pool.d.ts +3 -0
  228. package/dist/modules/mysql/pool.js +88 -0
  229. package/dist/modules/mysql/query.d.ts +12 -0
  230. package/dist/modules/mysql/query.js +21 -0
  231. package/dist/modules/mysql/schema.d.ts +43 -0
  232. package/dist/modules/mysql/schema.js +340 -0
  233. package/dist/modules/mysql/schema.test.d.ts +1 -0
  234. package/dist/modules/mysql/sessions.d.ts +33 -0
  235. package/dist/modules/mysql/sessions.js +46 -0
  236. package/dist/modules/mysql/spaceTokens.d.ts +11 -0
  237. package/dist/modules/mysql/spaceTokens.js +59 -0
  238. package/dist/modules/mysql/store.integration.test.d.ts +1 -0
  239. package/dist/modules/rsc/connectorRscData.d.ts +25 -0
  240. package/dist/modules/rsc/connectorRscData.js +51 -0
  241. package/dist/modules/rsc/connectorRscData.test.d.ts +1 -0
  242. package/dist/modules/rsc/handler.js +16 -3
  243. package/dist/modules/rsc/matchRscPage.d.ts +14 -0
  244. package/dist/modules/rsc/matchRscPage.js +26 -0
  245. package/dist/modules/rsc/resolveRscData.d.ts +14 -1
  246. package/dist/modules/rsc/resolveRscData.js +23 -34
  247. package/dist/modules/ssr/Component.d.ts +6 -2
  248. package/dist/modules/ssr/Component.js +3 -1
  249. package/dist/modules/ssr/draftSession.test.d.ts +1 -0
  250. package/dist/modules/ssr/handler.js +15 -2
  251. package/dist/modules/ssr/loadPluginComponents.js +22 -5
  252. package/dist/modules/ssr/prepareRender.js +87 -8
  253. package/dist/modules/ssr/prepareRender.test.d.ts +1 -0
  254. package/dist/modules/ssr/preview.d.ts +21 -8
  255. package/dist/modules/ssr/preview.js +38 -14
  256. package/dist/modules/ssr/registerExternalPlugins.js +2 -2
  257. package/dist/modules/ssr/resolvePageSeo.d.ts +18 -0
  258. package/dist/modules/ssr/resolvePageSeo.js +26 -0
  259. package/dist/modules/ssr/resolvePageSeo.test.d.ts +1 -0
  260. package/dist/modules/ssr/template.test.d.ts +1 -0
  261. package/dist/modules/ssr/views/template.ejs +71 -5
  262. package/dist/mysql.d.ts +26 -0
  263. package/dist/mysql.js +4 -0
  264. package/dist/oauth.d.ts +24 -0
  265. package/dist/oauth.js +10 -0
  266. package/dist/plugins/compile.d.ts +1 -0
  267. package/dist/plugins/compile.js +37 -3
  268. package/dist/plugins/manager.d.ts +40 -0
  269. package/dist/plugins/manager.js +113 -13
  270. package/dist/plugins/manager.test.d.ts +1 -0
  271. package/package.json +43 -14
  272. package/skills/plitzi-authoring/SKILL.md +252 -0
  273. /package/dist/{modules/actions/handler.test.d.ts → adapters/cloudAdapters.test.d.ts} +0 -0
  274. /package/dist/modules/actions/{handler.d.ts → connectorWrite.d.ts} +0 -0
@@ -0,0 +1,59 @@
1
+ import { renderTaskParams } from "./helpers.js";
2
+ //#region src/modules/actions/tasks/db.ts
3
+ var TEMPLATE = /\{\{/;
4
+ var parseParams = (value) => {
5
+ if (Array.isArray(value)) return value;
6
+ if (typeof value !== "string" || value.trim() === "") return [];
7
+ try {
8
+ const parsed = JSON.parse(value);
9
+ return Array.isArray(parsed) ? parsed : [parsed];
10
+ } catch {
11
+ throw new Error("Query parameters are not a valid JSON array");
12
+ }
13
+ };
14
+ var dbTasks = [{
15
+ namespace: "db",
16
+ action: "query",
17
+ title: "Database Query",
18
+ description: "Runs a parameterized statement against a database this space declared as a credential",
19
+ rawParams: true,
20
+ params: {
21
+ credential: {
22
+ type: "text",
23
+ canBind: true,
24
+ defaultValue: "",
25
+ label: "Connection (credential)"
26
+ },
27
+ sql: {
28
+ type: "codemirror-text",
29
+ canBind: false,
30
+ defaultValue: "",
31
+ label: "SQL (no templates)"
32
+ },
33
+ params: {
34
+ type: "codemirror-json",
35
+ canBind: true,
36
+ defaultValue: "[]",
37
+ label: "Bound parameters"
38
+ }
39
+ },
40
+ run: async (raw, ctx) => {
41
+ if (!raw.credential) throw new Error("The query names no connection credential");
42
+ if (raw.sql.trim() === "") throw new Error("The query is empty");
43
+ if (TEMPLATE.test(raw.sql)) throw new Error("The statement must be a literal: put the value in `params` and use a placeholder");
44
+ const credential = await ctx.credential(raw.credential);
45
+ if (!credential) throw new Error(`Credential "${raw.credential}" is not available for this space`);
46
+ const { engine, dsn } = credential;
47
+ if (!engine || !dsn) throw new Error(`Credential "${raw.credential}" carries no engine and dsn`);
48
+ const driver = ctx.dbDrivers.find((item) => item.engine === engine);
49
+ if (!driver) throw new Error(`This server has no driver for "${engine}"`);
50
+ const rendered = await renderTaskParams({ params: raw.params }, ctx, raw.credential);
51
+ const rows = await driver.query(dsn, raw.sql, parseParams(rendered.params), ctx.signal);
52
+ return {
53
+ rows,
54
+ count: rows.length
55
+ };
56
+ }
57
+ }];
58
+ //#endregion
59
+ export { dbTasks };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import { ActionTask } from '../types';
2
+ export declare const flowTasks: ActionTask<Record<string, unknown>>[];
3
+ export declare const streamTasks: ActionTask<Record<string, unknown>>[];
@@ -0,0 +1,109 @@
1
+ import onAbort from "../../../helpers/onAbort.js";
2
+ //#region src/modules/actions/tasks/flow.ts
3
+ var MAX_DELAY_MS = 5e3;
4
+ /**
5
+ * Pauses the flow.
6
+ *
7
+ * Capped hard: a run holds a connection and a concurrency slot for its whole life, so an authored `delay` is a way
8
+ * to spend both on nothing. Anything longer than this is a schedule, not a step.
9
+ */
10
+ var delay = {
11
+ namespace: "flow",
12
+ action: "delay",
13
+ title: "Delay",
14
+ params: { milliseconds: {
15
+ type: "text",
16
+ canBind: true,
17
+ defaultValue: "1000",
18
+ label: "Milliseconds"
19
+ } },
20
+ run: async ({ milliseconds }, ctx) => {
21
+ const parsed = typeof milliseconds === "number" ? milliseconds : Number.parseInt(milliseconds, 10);
22
+ const waitMs = Math.min(Number.isNaN(parsed) || parsed < 0 ? 0 : parsed, MAX_DELAY_MS);
23
+ await new Promise((resolve) => {
24
+ const timer = setTimeout(resolve, waitMs);
25
+ onAbort(ctx.signal, () => {
26
+ clearTimeout(timer);
27
+ resolve();
28
+ });
29
+ });
30
+ return { waited: waitMs };
31
+ }
32
+ };
33
+ /** Ends the run as failed, on purpose. The message reaches the trace, never the caller. */
34
+ var fail = {
35
+ namespace: "flow",
36
+ action: "fail",
37
+ title: "Fail",
38
+ params: { message: {
39
+ type: "text",
40
+ canBind: true,
41
+ defaultValue: "",
42
+ label: "Message"
43
+ } },
44
+ run: ({ message }) => {
45
+ throw new Error(message || "Action failed");
46
+ }
47
+ };
48
+ /**
49
+ * Declares what the caller gets back — and IS the declaration.
50
+ *
51
+ * The flow scope is not the answer: it holds every node's raw result, including whatever a fetch happened to
52
+ * return. This step is the one place that decides what leaves the server, and what it names is exactly what the
53
+ * caller receives.
54
+ *
55
+ * There is no separate output contract on the document, deliberately. Declaring the shape before the steps exist
56
+ * asks an author to know what a flow returns before writing it, and leaves two places to keep in step; the values
57
+ * here are the contract, and the builder derives the field list from them for bindings.
58
+ *
59
+ * It must be the LAST step: the runner reads the last one that ran, so a step after it is work whose result
60
+ * nobody asked for — the validator says so.
61
+ */
62
+ var output = {
63
+ namespace: "flow",
64
+ action: "output",
65
+ title: "Output",
66
+ params: { values: {
67
+ type: "codemirror-json",
68
+ canBind: true,
69
+ defaultValue: "{}",
70
+ label: "Values"
71
+ } },
72
+ run: ({ values }) => {
73
+ if (typeof values !== "string") return values;
74
+ try {
75
+ return JSON.parse(values);
76
+ } catch {
77
+ throw new Error("Output values are not valid JSON");
78
+ }
79
+ }
80
+ };
81
+ /**
82
+ * Pushes progress to a caller watching the run.
83
+ *
84
+ * A no-op when nobody negotiated a stream, and deliberately so: a flow is authored once and runs both ways, so a
85
+ * step that reported progress must not fail on the request/response path just because nobody is listening.
86
+ */
87
+ var emit = {
88
+ namespace: "stream",
89
+ action: "emit",
90
+ title: "Report Progress",
91
+ params: { chunk: {
92
+ type: "codemirror-text",
93
+ canBind: true,
94
+ defaultValue: "",
95
+ label: "Chunk"
96
+ } },
97
+ run: ({ chunk }, ctx) => {
98
+ ctx.emit(chunk);
99
+ return { emitted: true };
100
+ }
101
+ };
102
+ var flowTasks = [
103
+ delay,
104
+ fail,
105
+ output
106
+ ];
107
+ var streamTasks = [emit];
108
+ //#endregion
109
+ export { flowTasks, streamTasks };
@@ -0,0 +1,16 @@
1
+ import { ActionTaskContext } from '../types';
2
+ /**
3
+ * Renders a task's own params, with its own credential in scope.
4
+ *
5
+ * This is the shape every task that talks to a third party takes — `http.request` today, `apiCall` and whatever
6
+ * else tomorrow — and it exists so each of them does not invent its own answer to the same question.
7
+ *
8
+ * The credential is resolved HERE, inside the task, and never enters the flow scope. That is the whole point:
9
+ * a secret in the run's scope is interpolable by every other node, including the one that returns values to the
10
+ * browser, and no amount of care in this task would stop that. What a flow can reach is what its tasks chose to
11
+ * hand back — a credential is not that.
12
+ *
13
+ * Tasks using this declare `rawParams: true`, because the runner must not have resolved the params first: a
14
+ * `{{credential.*}}` token would then have been spent against a scope that has no credential in it.
15
+ */
16
+ export declare const renderTaskParams: <T extends Record<string, unknown>>(params: T, ctx: ActionTaskContext, credentialId?: string) => Promise<T>;
@@ -0,0 +1,30 @@
1
+ import { processTwig } from "@plitzi/sdk-shared/helpers/twigWrapper";
2
+ //#region src/modules/actions/tasks/helpers.ts
3
+ /**
4
+ * Renders a task's own params, with its own credential in scope.
5
+ *
6
+ * This is the shape every task that talks to a third party takes — `http.request` today, `apiCall` and whatever
7
+ * else tomorrow — and it exists so each of them does not invent its own answer to the same question.
8
+ *
9
+ * The credential is resolved HERE, inside the task, and never enters the flow scope. That is the whole point:
10
+ * a secret in the run's scope is interpolable by every other node, including the one that returns values to the
11
+ * browser, and no amount of care in this task would stop that. What a flow can reach is what its tasks chose to
12
+ * hand back — a credential is not that.
13
+ *
14
+ * Tasks using this declare `rawParams: true`, because the runner must not have resolved the params first: a
15
+ * `{{credential.*}}` token would then have been spent against a scope that has no credential in it.
16
+ */
17
+ var renderTaskParams = async (params, ctx, credentialId) => {
18
+ const credential = credentialId ? await ctx.credential(credentialId) : void 0;
19
+ if (credentialId && !credential) throw new Error(`Credential "${credentialId}" is not available for this space`);
20
+ const scope = {
21
+ ...ctx.scope,
22
+ ...credential ? { credential } : {}
23
+ };
24
+ return Object.entries(params).reduce((acum, [key, value]) => {
25
+ acum[key] = typeof value === "string" ? processTwig(value, scope, false, true) : value;
26
+ return acum;
27
+ }, {});
28
+ };
29
+ //#endregion
30
+ export { renderTaskParams };
@@ -0,0 +1,2 @@
1
+ import { ActionTask } from '../types';
2
+ export declare const httpTasks: ActionTask<Record<string, unknown>>[];
@@ -0,0 +1,111 @@
1
+ import { assertOutboundAllowed } from "../../../helpers/outboundGuard.js";
2
+ import { renderTaskParams } from "./helpers.js";
3
+ //#region src/modules/actions/tasks/http.ts
4
+ var BODYLESS = ["GET", "HEAD"];
5
+ var parseJsonParam = (value, label) => {
6
+ if (value === void 0 || value === "") return {};
7
+ if (typeof value === "object" && value !== null) return value;
8
+ if (typeof value !== "string") throw new Error(`${label} is not valid JSON`);
9
+ try {
10
+ const parsed = JSON.parse(value);
11
+ return parsed !== null && typeof parsed === "object" ? parsed : {};
12
+ } catch {
13
+ throw new Error(`${label} is not valid JSON`);
14
+ }
15
+ };
16
+ var httpTasks = [{
17
+ namespace: "http",
18
+ action: "request",
19
+ title: "HTTP Request",
20
+ rawParams: true,
21
+ params: {
22
+ credential: {
23
+ type: "text",
24
+ canBind: true,
25
+ defaultValue: "",
26
+ label: "Credential"
27
+ },
28
+ url: {
29
+ type: "text",
30
+ canBind: true,
31
+ defaultValue: "",
32
+ label: "URL"
33
+ },
34
+ method: {
35
+ type: "select",
36
+ defaultValue: "GET",
37
+ label: "Method",
38
+ options: [
39
+ {
40
+ label: "GET",
41
+ value: "GET"
42
+ },
43
+ {
44
+ label: "POST",
45
+ value: "POST"
46
+ },
47
+ {
48
+ label: "PUT",
49
+ value: "PUT"
50
+ },
51
+ {
52
+ label: "PATCH",
53
+ value: "PATCH"
54
+ },
55
+ {
56
+ label: "DELETE",
57
+ value: "DELETE"
58
+ }
59
+ ]
60
+ },
61
+ headers: {
62
+ type: "codemirror-json",
63
+ canBind: true,
64
+ defaultValue: "{}",
65
+ label: "Headers"
66
+ },
67
+ body: {
68
+ type: "codemirror-json",
69
+ canBind: true,
70
+ defaultValue: "",
71
+ label: "Body",
72
+ when: (params) => params.method !== "GET"
73
+ }
74
+ },
75
+ run: async (raw, ctx) => {
76
+ const params = await renderTaskParams(raw, ctx, raw.credential || void 0);
77
+ const method = (params.method || "GET").toUpperCase();
78
+ let url;
79
+ try {
80
+ url = new URL(params.url);
81
+ } catch {
82
+ throw new Error("Request URL is not a valid absolute URL");
83
+ }
84
+ await assertOutboundAllowed(url);
85
+ const headers = Object.entries(parseJsonParam(params.headers, "Headers")).reduce((acum, [key, value]) => {
86
+ acum[key] = typeof value === "string" ? value : JSON.stringify(value);
87
+ return acum;
88
+ }, {});
89
+ const hasBody = !BODYLESS.includes(method) && params.body !== "";
90
+ const declaresContentType = Object.keys(headers).some((name) => name.toLowerCase() === "content-type");
91
+ if (hasBody && !declaresContentType) headers["Content-Type"] = "application/json";
92
+ const response = await ctx.fetch(url.toString(), {
93
+ method,
94
+ headers,
95
+ body: hasBody ? JSON.stringify(parseJsonParam(params.body, "Body")) : void 0,
96
+ signal: ctx.signal
97
+ });
98
+ const text = await response.text();
99
+ let data = text;
100
+ try {
101
+ data = JSON.parse(text);
102
+ } catch {}
103
+ return {
104
+ status: response.status,
105
+ ok: response.ok,
106
+ data
107
+ };
108
+ }
109
+ }];
110
+ //#endregion
111
+ export { httpTasks };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import { ActionTask } from '../types';
2
+ export declare const kvTasks: ActionTask<Record<string, unknown>>[];
@@ -0,0 +1,102 @@
1
+ //#region src/modules/actions/tasks/kv.ts
2
+ var toNumber = (value, fallback) => {
3
+ if (value === void 0 || value === "") return fallback;
4
+ const parsed = typeof value === "number" ? value : Number.parseInt(value, 10);
5
+ return Number.isFinite(parsed) ? parsed : fallback;
6
+ };
7
+ var kvTasks = [
8
+ {
9
+ namespace: "kv",
10
+ action: "get",
11
+ title: "Read Value",
12
+ params: { key: {
13
+ type: "text",
14
+ canBind: true,
15
+ defaultValue: "",
16
+ label: "Key"
17
+ } },
18
+ run: async ({ key }, ctx) => ({ value: await ctx.kv.get(key) ?? null })
19
+ },
20
+ {
21
+ namespace: "kv",
22
+ action: "set",
23
+ title: "Write Value",
24
+ params: {
25
+ key: {
26
+ type: "text",
27
+ canBind: true,
28
+ defaultValue: "",
29
+ label: "Key"
30
+ },
31
+ value: {
32
+ type: "codemirror-text",
33
+ canBind: true,
34
+ defaultValue: "",
35
+ label: "Value"
36
+ },
37
+ ttlSeconds: {
38
+ type: "text",
39
+ canBind: true,
40
+ defaultValue: "",
41
+ label: "TTL (seconds)"
42
+ }
43
+ },
44
+ run: async ({ key, value, ttlSeconds }, ctx) => {
45
+ const ttl = ttlSeconds === "" ? void 0 : toNumber(ttlSeconds, 0) || void 0;
46
+ await ctx.kv.set(key, value, ttl);
47
+ return {
48
+ key,
49
+ stored: true
50
+ };
51
+ }
52
+ },
53
+ {
54
+ namespace: "kv",
55
+ action: "increment",
56
+ title: "Increment Counter",
57
+ params: {
58
+ key: {
59
+ type: "text",
60
+ canBind: true,
61
+ defaultValue: "",
62
+ label: "Key"
63
+ },
64
+ amount: {
65
+ type: "text",
66
+ canBind: true,
67
+ defaultValue: "1",
68
+ label: "Amount"
69
+ },
70
+ ttlSeconds: {
71
+ type: "text",
72
+ canBind: true,
73
+ defaultValue: "",
74
+ label: "TTL (seconds)"
75
+ }
76
+ },
77
+ run: async ({ key, amount, ttlSeconds }, ctx) => {
78
+ const ttl = ttlSeconds === "" ? void 0 : toNumber(ttlSeconds, 0) || void 0;
79
+ return { value: await ctx.kv.increment(key, toNumber(amount, 1), ttl) };
80
+ }
81
+ },
82
+ {
83
+ namespace: "kv",
84
+ action: "delete",
85
+ title: "Delete Value",
86
+ params: { key: {
87
+ type: "text",
88
+ canBind: true,
89
+ defaultValue: "",
90
+ label: "Key"
91
+ } },
92
+ run: async ({ key }, ctx) => {
93
+ await ctx.kv.delete(key);
94
+ return {
95
+ key,
96
+ deleted: true
97
+ };
98
+ }
99
+ }
100
+ ];
101
+ //#endregion
102
+ export { kvTasks };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import { ActionTask, ActionTaskRegistry } from '../types';
2
+ export declare const taskName: (task: Pick<ActionTask, "namespace" | "action">) => string;
3
+ /**
4
+ * Builds the set of tasks this server can run.
5
+ *
6
+ * Validation is at BOOT and it throws, because every alternative is worse: a task registered under a malformed
7
+ * name is unreachable from any document, and one shadowing a built-in silently changes what every existing action
8
+ * in that deployment does. Both are invisible until a run misbehaves in production.
9
+ */
10
+ export declare const createTaskRegistry: (custom?: ActionTask<never>[], hasDbDrivers?: boolean) => ActionTaskRegistry;
@@ -0,0 +1,36 @@
1
+ import { builtinTasks } from "./builtins.js";
2
+ import { dbTasks } from "./db.js";
3
+ //#region src/modules/actions/tasks/registry.ts
4
+ var NAME_PATTERN = /^[a-z][a-zA-Z0-9]*$/;
5
+ var taskName = (task) => `${task.namespace}.${task.action}`;
6
+ var reservedNamespaces = new Set([...builtinTasks, ...dbTasks].map((task) => task.namespace));
7
+ /**
8
+ * Builds the set of tasks this server can run.
9
+ *
10
+ * Validation is at BOOT and it throws, because every alternative is worse: a task registered under a malformed
11
+ * name is unreachable from any document, and one shadowing a built-in silently changes what every existing action
12
+ * in that deployment does. Both are invisible until a run misbehaves in production.
13
+ */
14
+ var createTaskRegistry = (custom = [], hasDbDrivers = false) => {
15
+ const tasks = /* @__PURE__ */ new Map();
16
+ (hasDbDrivers ? [...builtinTasks, ...dbTasks] : builtinTasks).forEach((task) => tasks.set(taskName(task), {
17
+ ...task,
18
+ name: taskName(task)
19
+ }));
20
+ custom.forEach((task) => {
21
+ if (!NAME_PATTERN.test(task.namespace) || !NAME_PATTERN.test(task.action)) throw new Error(`[Actions] Invalid task name "${taskName(task)}": expected camelCase namespace and action`);
22
+ if (reservedNamespaces.has(task.namespace)) throw new Error(`[Actions] Namespace "${task.namespace}" is reserved by a built-in task set`);
23
+ const name = taskName(task);
24
+ if (tasks.has(name)) throw new Error(`[Actions] Task "${name}" is registered twice`);
25
+ tasks.set(name, {
26
+ ...task,
27
+ name
28
+ });
29
+ });
30
+ return {
31
+ get: (name) => tasks.get(name),
32
+ list: () => [...tasks.values()]
33
+ };
34
+ };
35
+ //#endregion
36
+ export { createTaskRegistry, taskName };
@@ -0,0 +1,2 @@
1
+ import { ActionTask } from '../types';
2
+ export declare const transformTasks: ActionTask<Record<string, unknown>>[];
@@ -0,0 +1,34 @@
1
+ import { processTwig } from "@plitzi/sdk-shared/helpers/twigWrapper";
2
+ var transformTasks = [{
3
+ namespace: "transform",
4
+ action: "template",
5
+ title: "Template",
6
+ rawParams: true,
7
+ params: { template: {
8
+ type: "codemirror-text",
9
+ canBind: true,
10
+ defaultValue: "",
11
+ label: "Template"
12
+ } },
13
+ run: ({ template: source }, ctx) => ({ value: typeof source === "string" ? processTwig(source, { ...ctx.scope }) : "" })
14
+ }, {
15
+ namespace: "transform",
16
+ action: "json",
17
+ title: "Parse JSON",
18
+ params: { value: {
19
+ type: "codemirror-text",
20
+ canBind: true,
21
+ defaultValue: "",
22
+ label: "Value"
23
+ } },
24
+ run: ({ value }) => {
25
+ if (typeof value !== "string") return { value };
26
+ try {
27
+ return { value: JSON.parse(value) };
28
+ } catch {
29
+ throw new Error("Value is not valid JSON");
30
+ }
31
+ }
32
+ }];
33
+ //#endregion
34
+ export { transformTasks };
@@ -0,0 +1,24 @@
1
+ import { RawResponse } from '../../../helpers/buildResponseHelpers';
2
+ import { ActionsModule } from '../index';
3
+ import { SSRPageServerConfig, SSRRequest, SSRResponseHelpers } from '@plitzi/sdk-shared';
4
+ export type ActionCallDeps = {
5
+ req: SSRRequest;
6
+ res: SSRResponseHelpers;
7
+ /** The raw response, for the streaming path alone: SSE cannot go through the one-shot helpers. */
8
+ raw: RawResponse;
9
+ config: SSRPageServerConfig;
10
+ module: ActionsModule;
11
+ /** The request's own signal: a caller that hangs up stops the run rather than paying for it to finish. */
12
+ signal: AbortSignal;
13
+ /** Who is asking, for the single-flight key and for cancellation ownership. */
14
+ callerId: string;
15
+ lineage: string[];
16
+ };
17
+ /**
18
+ * Handles an action-addressed call.
19
+ *
20
+ * The browser names an action and hands it inputs. Everything that decides whether the run may happen — the
21
+ * document, the access rule, the input contract, the lineage — is the runner's, so a deployment mounting its own
22
+ * trigger cannot end up with a weaker set of checks than this endpoint applies.
23
+ */
24
+ export declare const handleActionCall: (deps: ActionCallDeps) => Promise<void>;