@plitzi/sdk-shared 0.37.9 → 0.37.10

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 (130) hide show
  1. package/CHANGELOG.md +585 -0
  2. package/dist/actions/index.d.ts +1 -1
  3. package/dist/actions/index.mjs +3 -3
  4. package/dist/actions/triggerParams.mjs +7 -6
  5. package/dist/actions/validateDocument.d.ts +3 -0
  6. package/dist/actions/validateDocument.mjs +89 -88
  7. package/dist/authoring/elementCallbacks.d.ts +65 -0
  8. package/dist/authoring/elementCallbacks.mjs +72 -8
  9. package/dist/authoring/index.mjs +3 -3
  10. package/dist/builder/contexts/BuilderContext.d.ts +18 -7
  11. package/dist/connectors/index.d.ts +1 -1
  12. package/dist/connectors/index.mjs +2 -2
  13. package/dist/connectors/validateManifest.d.ts +3 -0
  14. package/dist/connectors/validateManifest.mjs +77 -76
  15. package/dist/dataSource/computed.mjs +25 -29
  16. package/dist/dataSource/globalSources.d.ts +15 -0
  17. package/dist/dataSource/globalSources.mjs +13 -0
  18. package/dist/dataSource/index.d.ts +2 -0
  19. package/dist/dataSource/index.mjs +8 -7
  20. package/dist/devTools/utils/PlitziConsole.d.ts +9 -0
  21. package/dist/devTools/utils/PlitziConsole.mjs +27 -7
  22. package/dist/flags/flagsCookie.d.ts +26 -0
  23. package/dist/flags/flagsCookie.mjs +20 -0
  24. package/dist/flags/index.d.ts +3 -0
  25. package/dist/flags/index.mjs +4 -0
  26. package/dist/flags/resolveFlags.d.ts +60 -0
  27. package/dist/flags/resolveFlags.mjs +38 -0
  28. package/dist/flags/schemaFlag.d.ts +11 -0
  29. package/dist/flags/schemaFlag.mjs +9 -0
  30. package/dist/flags/useFlagResolution.d.ts +13 -0
  31. package/dist/flags/useFlagResolution.mjs +43 -0
  32. package/dist/helpers/eventTarget.d.ts +10 -0
  33. package/dist/helpers/eventTarget.mjs +4 -0
  34. package/dist/helpers/images.d.ts +18 -0
  35. package/dist/helpers/images.mjs +13 -0
  36. package/dist/helpers/index.d.ts +3 -0
  37. package/dist/helpers/index.mjs +21 -18
  38. package/dist/helpers/interval.d.ts +18 -0
  39. package/dist/helpers/interval.mjs +7 -0
  40. package/dist/helpers/isRecord.d.ts +2 -0
  41. package/dist/helpers/isRecord.mjs +4 -0
  42. package/dist/helpers/scroll.d.ts +42 -0
  43. package/dist/helpers/scroll.mjs +30 -0
  44. package/dist/helpers/twigWrapper/TemplateCache/TemplateCache.mjs +1 -1
  45. package/dist/helpers/twigWrapper/filters/filters.mjs +38 -2
  46. package/dist/history/describe.mjs +3 -1
  47. package/dist/history/diff.d.ts +1 -1
  48. package/dist/history/diff.mjs +1 -0
  49. package/dist/history/types.d.ts +1 -1
  50. package/dist/hooks/index.mjs +5 -5
  51. package/dist/index.d.ts +1 -0
  52. package/dist/index.mjs +90 -76
  53. package/dist/navigation/routes.mjs +6 -4
  54. package/dist/network/graphql/builder/Mutations/Space/SpaceAddSnippetMutation.d.ts +2 -0
  55. package/dist/network/graphql/builder/Mutations/Space/SpaceAddSnippetMutation.mjs +4 -0
  56. package/dist/network/graphql/builder/Mutations/Space/flags/SpacePublishFlagsMutation.d.ts +12 -0
  57. package/dist/network/graphql/builder/Mutations/Space/flags/SpacePublishFlagsMutation.mjs +4 -0
  58. package/dist/network/graphql/builder/Mutations/Space/flags/SpaceRemoveFlagMutation.d.ts +2 -0
  59. package/dist/network/graphql/builder/Mutations/Space/flags/SpaceRemoveFlagMutation.mjs +4 -0
  60. package/dist/network/graphql/builder/Mutations/Space/flags/SpaceSetFlagMutation.d.ts +3 -0
  61. package/dist/network/graphql/builder/Mutations/Space/flags/SpaceSetFlagMutation.mjs +4 -0
  62. package/dist/network/graphql/builder/Mutations/index.d.ts +5 -1
  63. package/dist/network/graphql/builder/Mutations/index.mjs +122 -116
  64. package/dist/network/graphql/builder/Queries/InitQuery.d.ts +3 -1
  65. package/dist/network/graphql/builder/Queries/InitQuery.mjs +1 -1
  66. package/dist/network/graphql/builder/Queries/Space/SpaceIssuesQuery.d.ts +16 -2
  67. package/dist/network/graphql/builder/Queries/Space/SpaceIssuesQuery.mjs +1 -1
  68. package/dist/network/graphql/builder/Queries/index.d.ts +1 -1
  69. package/dist/network/graphql/sdk/Queries/InitQuery.d.ts +1 -1
  70. package/dist/network/graphql/sdk/Queries/InitQuery.mjs +1 -1
  71. package/dist/network/index.mjs +8 -7
  72. package/dist/network/spaceEvents.d.ts +12 -6
  73. package/dist/network/spaceEvents.mjs +153 -154
  74. package/dist/realtime/client.mjs +123 -95
  75. package/dist/realtime/topics.mjs +18 -17
  76. package/dist/schema/anchor.d.ts +8 -0
  77. package/dist/schema/anchor.mjs +4 -0
  78. package/dist/schema/index.d.ts +2 -0
  79. package/dist/schema/index.mjs +6 -4
  80. package/dist/schema/serverElements.d.ts +6 -2
  81. package/dist/schema/serverElements.mjs +17 -16
  82. package/dist/schema/snippet.d.ts +7 -0
  83. package/dist/schema/snippet.mjs +9 -0
  84. package/dist/schema/wire.d.ts +11 -0
  85. package/dist/schema/wire.mjs +27 -0
  86. package/dist/server/actions/useImagesSync.d.ts +9 -0
  87. package/dist/server/actions/useImagesSync.mjs +7 -0
  88. package/dist/server/rsc/refreshRsc.mjs +8 -8
  89. package/dist/source/snapshot.mjs +23 -22
  90. package/dist/state/paintedState.mjs +13 -12
  91. package/dist/state/runtimeStatePersist.mjs +50 -49
  92. package/dist/store/index.d.ts +45 -45
  93. package/dist/style/breakpoints.d.ts +11 -0
  94. package/dist/style/breakpoints.mjs +8 -0
  95. package/dist/style/displayModes.d.ts +5 -0
  96. package/dist/style/displayModes.mjs +8 -0
  97. package/dist/style/fontValidation.mjs +52 -51
  98. package/dist/style/fonts.d.ts +0 -12
  99. package/dist/style/fonts.mjs +11 -11
  100. package/dist/style/index.d.ts +4 -0
  101. package/dist/style/index.mjs +11 -7
  102. package/dist/style/layoutGrid.d.ts +30 -0
  103. package/dist/style/layoutGrid.mjs +33 -0
  104. package/dist/style/notifications.d.ts +52 -0
  105. package/dist/style/notifications.mjs +55 -0
  106. package/dist/style/snippetStyle.d.ts +23 -0
  107. package/dist/style/snippetStyle.mjs +32 -0
  108. package/dist/style/styleConstants.d.ts +7 -2
  109. package/dist/style/styleConstants.mjs +10 -0
  110. package/dist/style/styleStates.d.ts +11 -2
  111. package/dist/style/styleStates.mjs +12 -9
  112. package/dist/theme/ThemeProvider.mjs +20 -20
  113. package/dist/types/CommonTypes.d.ts +3 -0
  114. package/dist/types/DevToolsTypes.d.ts +29 -4
  115. package/dist/types/EventBridgeTypes.d.ts +2 -2
  116. package/dist/types/PluginTypes.d.ts +1 -1
  117. package/dist/types/ResourceTypes.d.ts +2 -2
  118. package/dist/types/SchemaTypes.d.ts +62 -3
  119. package/dist/types/ServerTypes.d.ts +47 -0
  120. package/dist/types/SnippetTypes.d.ts +28 -0
  121. package/dist/types/StoreTypes.d.ts +25 -0
  122. package/dist/types/StyleTypes.d.ts +1 -1
  123. package/dist/types/index.d.ts +1 -1
  124. package/package.json +104 -8
  125. package/tailwind.config.js +1 -6
  126. package/vite.config.ts +16 -4
  127. package/dist/network/graphql/builder/Mutations/Space/SpaceAddTemplateMutation.d.ts +0 -2
  128. package/dist/network/graphql/builder/Mutations/Space/SpaceAddTemplateMutation.mjs +0 -4
  129. package/dist/types/TemplateTypes.d.ts +0 -20
  130. /package/dist/types/{TemplateTypes.mjs → SnippetTypes.mjs} +0 -0
@@ -1,5 +1,5 @@
1
1
  import { BODYLESS_METHODS as e, CONNECTOR_HTTP_METHODS as t, DEFAULT_READ_ENDPOINT as n, EMPTY_RESPONSE_METHODS as r, READ_ENDPOINT_NAMES as i, WRITE_ENDPOINT_NAMES as a } from "./constants.mjs";
2
2
  import { connectorTokens as o, getConnectorTokens as s } from "./manifestTokens.mjs";
3
3
  import { connectorPresets as c, emptyManifest as l } from "./presets.mjs";
4
- import { validateConnectorManifest as u } from "./validateManifest.mjs";
5
- export { e as BODYLESS_METHODS, t as CONNECTOR_HTTP_METHODS, n as DEFAULT_READ_ENDPOINT, r as EMPTY_RESPONSE_METHODS, i as READ_ENDPOINT_NAMES, a as WRITE_ENDPOINT_NAMES, c as connectorPresets, o as connectorTokens, l as emptyManifest, s as getConnectorTokens, u as validateConnectorManifest };
4
+ import { isConnectorManifestDraft as u, validateConnectorManifest as d } from "./validateManifest.mjs";
5
+ export { e as BODYLESS_METHODS, t as CONNECTOR_HTTP_METHODS, n as DEFAULT_READ_ENDPOINT, r as EMPTY_RESPONSE_METHODS, i as READ_ENDPOINT_NAMES, a as WRITE_ENDPOINT_NAMES, c as connectorPresets, o as connectorTokens, l as emptyManifest, s as getConnectorTokens, u as isConnectorManifestDraft, d as validateConnectorManifest };
@@ -1,3 +1,4 @@
1
+ import { ConnectorManifestDraft } from '../types';
1
2
  /**
2
3
  * The one connector-manifest validator.
3
4
  *
@@ -26,3 +27,5 @@ export type ConnectorManifestReport = {
26
27
  * Give it whatever you have — parsed JSON, an editor's working copy, a GraphQL argument. It never throws.
27
28
  */
28
29
  export declare const validateConnectorManifest: (input: unknown) => ConnectorManifestReport;
30
+ /** Whether a value read from outside — a deployment's store, a request — is a manifest the engine can run. */
31
+ export declare const isConnectorManifestDraft: (input: unknown) => input is ConnectorManifestDraft;
@@ -1,11 +1,12 @@
1
- import { BODYLESS_METHODS as e, CONNECTOR_HTTP_METHODS as t } from "./constants.mjs";
2
- import { connectorTokens as n } from "./manifestTokens.mjs";
1
+ import { isRecord as e } from "../helpers/isRecord.mjs";
2
+ import { BODYLESS_METHODS as t, CONNECTOR_HTTP_METHODS as n } from "./constants.mjs";
3
+ import { connectorTokens as r } from "./manifestTokens.mjs";
3
4
  //#region src/connectors/validateManifest.ts
4
- var r = [
5
+ var i = [
5
6
  "offset",
6
7
  "page",
7
8
  "cursor"
8
- ], i = [
9
+ ], a = [
9
10
  "text",
10
11
  "richText",
11
12
  "image",
@@ -20,7 +21,7 @@ var r = [
20
21
  "color",
21
22
  "option",
22
23
  "file"
23
- ], a = /\{\{\s*([^}]+?)\s*\}\}/g, o = (e) => typeof e == "object" && !!e && !Array.isArray(e), s = (e) => typeof e == "string" && e.trim() !== "", c = (e) => typeof e == "string" ? e : JSON.stringify(e), l = (e) => [...e.matchAll(a)].map((e) => e[1]), u = (e, t) => n.some((n) => n.scopes.includes(t) ? n.value.endsWith(".") ? e.startsWith(n.value) : e === n.value : !1), d = (e, t, n, r) => {
24
+ ], o = /\{\{\s*([^}]+?)\s*\}\}/g, s = (e) => typeof e == "string" && e.trim() !== "", c = (e) => typeof e == "string" ? e : JSON.stringify(e), l = (e) => [...e.matchAll(o)].map((e) => e[1]), u = (e, t) => r.some((n) => n.scopes.includes(t) ? n.value.endsWith(".") ? e.startsWith(n.value) : e === n.value : !1), d = (e, t, n, r) => {
24
25
  e.errors.push({
25
26
  path: t,
26
27
  message: n,
@@ -32,35 +33,35 @@ var r = [
32
33
  message: n,
33
34
  ...r === void 0 ? {} : { hint: r }
34
35
  });
35
- }, p = (e, t, n, r) => {
36
- if (t !== void 0) {
37
- if (!o(t)) {
38
- d(e, n, "Must be an object of string values", "Each entry is one name and its templated value");
36
+ }, p = (t, n, r, i) => {
37
+ if (n !== void 0) {
38
+ if (!e(n)) {
39
+ d(t, r, "Must be an object of string values", "Each entry is one name and its templated value");
39
40
  return;
40
41
  }
41
- for (let [i, a] of Object.entries(t)) {
42
+ for (let [e, a] of Object.entries(n)) {
42
43
  if (typeof a != "string") {
43
- d(e, `${n}.${i}`, "Must be a string", "Values are Twig templates the server renders per request");
44
+ d(t, `${r}.${e}`, "Must be a string", "Values are Twig templates the server renders per request");
44
45
  continue;
45
46
  }
46
- e.templates.push({
47
- path: `${n}.${i}`,
47
+ t.templates.push({
48
+ path: `${r}.${e}`,
48
49
  value: a,
49
- scope: r
50
+ scope: i
50
51
  });
51
52
  }
52
- return t;
53
+ return n;
53
54
  }
54
- }, m = (e, n, r, i) => {
55
- if (n === void 0) {
56
- i && d(e, r, "A write endpoint must declare its method", `One of ${t.join(", ")}`);
55
+ }, m = (e, t, r, i) => {
56
+ if (t === void 0) {
57
+ i && d(e, r, "A write endpoint must declare its method", `One of ${n.join(", ")}`);
57
58
  return;
58
59
  }
59
- if (typeof n != "string" || !t.includes(n)) {
60
- d(e, r, `"${c(n)}" is not an HTTP method`, `One of ${t.join(", ")}`);
60
+ if (typeof t != "string" || !n.includes(t)) {
61
+ d(e, r, `"${c(t)}" is not an HTTP method`, `One of ${n.join(", ")}`);
61
62
  return;
62
63
  }
63
- return n;
64
+ return t;
64
65
  }, h = (e, t, n, r) => {
65
66
  if (!s(t.path)) {
66
67
  d(e, `${n}.path`, "An endpoint needs a path", "It is appended to baseUrl, e.g. \"/api/{{resource}}\"");
@@ -73,25 +74,25 @@ var r = [
73
74
  });
74
75
  }, g = (e, t, n) => {
75
76
  if (t !== void 0) {
76
- if (typeof t != "string" || !r.includes(t)) {
77
- d(e, n, `"${c(t)}" is not a paging style`, `One of ${r.join(", ")}`);
77
+ if (typeof t != "string" || !i.includes(t)) {
78
+ d(e, n, `"${c(t)}" is not a paging style`, `One of ${i.join(", ")}`);
78
79
  return;
79
80
  }
80
81
  return t;
81
82
  }
82
- }, _ = (t, n, r, i) => {
83
- let a = `endpoints.read.${n}`;
84
- if (!o(r)) {
85
- d(t, a, "A read endpoint must be an object", "It declares at least a path");
83
+ }, _ = (n, r, i, a) => {
84
+ let o = `endpoints.read.${r}`;
85
+ if (!e(i)) {
86
+ d(n, o, "A read endpoint must be an object", "It declares at least a path");
86
87
  return;
87
88
  }
88
- h(t, r, a, "request");
89
- let s = m(t, r.method, `${a}.method`, !1) ?? "GET", c = p(t, r.query, `${a}.query`, "request");
90
- p(t, r.headers, `${a}.headers`, "request");
91
- let l = p(t, r.body, `${a}.body`, "request"), u = g(t, r.pagination, `${a}.pagination`) ?? i;
92
- if (l && e.includes(s) && f(t, `${a}.body`, `A ${s} request carries no body, so this one is never sent`, "Move these values into `query`, or read through POST if the provider expects a body"), u === void 0) return;
89
+ h(n, i, o, "request");
90
+ let s = m(n, i.method, `${o}.method`, !1) ?? "GET", c = p(n, i.query, `${o}.query`, "request");
91
+ p(n, i.headers, `${o}.headers`, "request");
92
+ let l = p(n, i.body, `${o}.body`, "request"), u = g(n, i.pagination, `${o}.pagination`) ?? a;
93
+ if (l && t.includes(s) && f(n, `${o}.body`, `A ${s} request carries no body, so this one is never sent`, "Move these values into `query`, or read through POST if the provider expects a body"), u === void 0) return;
93
94
  let _ = JSON.stringify({
94
- path: r.path,
95
+ path: i.path,
95
96
  query: c ?? {},
96
97
  body: l ?? {}
97
98
  }), v = {
@@ -99,70 +100,70 @@ var r = [
99
100
  page: "{{page}}",
100
101
  cursor: "{{cursor}}"
101
102
  }[u];
102
- v !== void 0 && !_.includes(v) && f(t, `${a}.query`, `"${n}" pages by ${u} but never uses ${v}, so every page resolves to the first one`, `Put ${v} in the query (or the path) this endpoint sends`);
103
- }, v = (e, t, n) => {
104
- let r = `endpoints.write.${t}`;
105
- if (!o(n)) {
106
- d(e, r, "A write endpoint must be an object", "It declares at least a method and a path");
103
+ v !== void 0 && !_.includes(v) && f(n, `${o}.query`, `"${r}" pages by ${u} but never uses ${v}, so every page resolves to the first one`, `Put ${v} in the query (or the path) this endpoint sends`);
104
+ }, v = (t, n, r) => {
105
+ let i = `endpoints.write.${n}`;
106
+ if (!e(r)) {
107
+ d(t, i, "A write endpoint must be an object", "It declares at least a method and a path");
107
108
  return;
108
109
  }
109
- h(e, n, r, "write"), m(e, n.method, `${r}.method`, !0), p(e, n.query, `${r}.query`, "write"), p(e, n.headers, `${r}.headers`, "write"), n.bodyPath !== void 0 && typeof n.bodyPath != "string" && d(e, `${r}.bodyPath`, "Must be a string", "It names where to nest the values, e.g. \"data\"");
110
- }, y = (e, t, n) => {
111
- if (!o(t)) {
112
- d(e, "endpoints", "A connector must declare its endpoints", "At least one read endpoint, usually \"list\"");
110
+ h(t, r, i, "write"), m(t, r.method, `${i}.method`, !0), p(t, r.query, `${i}.query`, "write"), p(t, r.headers, `${i}.headers`, "write"), r.bodyPath !== void 0 && typeof r.bodyPath != "string" && d(t, `${i}.bodyPath`, "Must be a string", "It names where to nest the values, e.g. \"data\"");
111
+ }, y = (t, n, r) => {
112
+ if (!e(n)) {
113
+ d(t, "endpoints", "A connector must declare its endpoints", "At least one read endpoint, usually \"list\"");
113
114
  return;
114
115
  }
115
- if (!o(t.read) || Object.keys(t.read).length === 0) d(e, "endpoints.read", "A connector needs at least one read endpoint", "Name it \"list\" — that is the one a provider element addresses when it names none");
116
- else for (let [r, i] of Object.entries(t.read)) _(e, r, i, n);
117
- if (t.write !== void 0) {
118
- if (!o(t.write)) {
119
- d(e, "endpoints.write", "Must be an object of endpoints keyed by name", "Omit it for a read-only connector");
116
+ if (!e(n.read) || Object.keys(n.read).length === 0) d(t, "endpoints.read", "A connector needs at least one read endpoint", "Name it \"list\" — that is the one a provider element addresses when it names none");
117
+ else for (let [e, i] of Object.entries(n.read)) _(t, e, i, r);
118
+ if (n.write !== void 0) {
119
+ if (!e(n.write)) {
120
+ d(t, "endpoints.write", "Must be an object of endpoints keyed by name", "Omit it for a read-only connector");
120
121
  return;
121
122
  }
122
- for (let [n, r] of Object.entries(t.write)) v(e, n, r);
123
+ for (let [e, r] of Object.entries(n.write)) v(t, e, r);
123
124
  }
124
- }, b = (e, t) => {
125
- if (t !== void 0) {
126
- if (!o(t)) {
127
- d(e, "auth", "Must be an object", "Shape: { in, name, value }");
125
+ }, b = (t, n) => {
126
+ if (n !== void 0) {
127
+ if (!e(n)) {
128
+ d(t, "auth", "Must be an object", "Shape: { in, name, value }");
128
129
  return;
129
130
  }
130
- if (t.in !== "header" && t.in !== "query" && d(e, "auth.in", "Auth travels in a header or a query parameter", "One of header, query"), s(t.name) || d(e, "auth.name", "Auth needs the name it is sent under", "e.g. \"Authorization\" for a bearer token"), typeof t.value != "string") {
131
- d(e, "auth.value", "Must be a string", "A template, e.g. \"Bearer {{credential.token}}\"");
131
+ if (n.in !== "header" && n.in !== "query" && d(t, "auth.in", "Auth travels in a header or a query parameter", "One of header, query"), s(n.name) || d(t, "auth.name", "Auth needs the name it is sent under", "e.g. \"Authorization\" for a bearer token"), typeof n.value != "string") {
132
+ d(t, "auth.value", "Must be a string", "A template, e.g. \"Bearer {{credential.token}}\"");
132
133
  return;
133
134
  }
134
- e.templates.push({
135
+ t.templates.push({
135
136
  path: "auth.value",
136
- value: t.value,
137
+ value: n.value,
137
138
  scope: "request"
138
139
  });
139
140
  }
140
141
  }, x = (e, t) => {
141
142
  let n = p(e, t, "operators", "filter");
142
143
  if (n) for (let [t, r] of Object.entries(n)) typeof r == "string" && !r.includes("=") && d(e, `operators.${t}`, `Operator "${t}" renders no "key=value" pair, so a filter using it is dropped`, "Write the full query entry, e.g. \"filters[{{field}}][$eq]={{value}}\"");
143
- }, S = (e, t) => {
144
- if (t !== void 0) {
145
- if (!o(t)) {
146
- d(e, "fields", "Must be an object of field name → type", `Types: ${i.join(", ")}`);
144
+ }, S = (t, n) => {
145
+ if (n !== void 0) {
146
+ if (!e(n)) {
147
+ d(t, "fields", "Must be an object of field name → type", `Types: ${a.join(", ")}`);
147
148
  return;
148
149
  }
149
- for (let [n, r] of Object.entries(t)) (typeof r != "string" || !i.includes(r)) && d(e, `fields.${n}`, `"${c(r)}" is not a field type`, `One of ${i.join(", ")}`);
150
+ for (let [e, r] of Object.entries(n)) (typeof r != "string" || !a.includes(r)) && d(t, `fields.${e}`, `"${c(r)}" is not a field type`, `One of ${a.join(", ")}`);
150
151
  }
151
152
  }, C = (e, t) => {
152
- let r = !1;
153
- for (let t of e.templates) for (let i of l(t.value)) i.startsWith("credential.") && (r = !0), u(i, t.scope) || f(e, t.path, `{{${i}}} is not a value the engine binds here, so it renders empty`, `Tokens available in this position: ${n.filter((e) => e.scopes.includes(t.scope)).map((e) => e.value).join(", ")}`);
154
- if (r && !s(t)) {
153
+ let n = !1;
154
+ for (let t of e.templates) for (let i of l(t.value)) i.startsWith("credential.") && (n = !0), u(i, t.scope) || f(e, t.path, `{{${i}}} is not a value the engine binds here, so it renders empty`, `Tokens available in this position: ${r.filter((e) => e.scopes.includes(t.scope)).map((e) => e.value).join(", ")}`);
155
+ if (n && !s(t)) {
155
156
  f(e, "credential", "This manifest reads {{credential.…}} but names no credential, so every request goes unauthenticated", "The connector still saves. Ask the space owner to create the credential and attach it — the secret is never part of the manifest.");
156
157
  return;
157
158
  }
158
- !r && s(t) && f(e, "credential", "A credential is attached but no template reads {{credential.…}}, so it is never sent", "Reference it where the provider expects it, e.g. auth.value = \"Bearer {{credential.token}}\"");
159
- }, w = (e) => {
160
- let t = {
159
+ !n && s(t) && f(e, "credential", "A credential is attached but no template reads {{credential.…}}, so it is never sent", "Reference it where the provider expects it, e.g. auth.value = \"Bearer {{credential.token}}\"");
160
+ }, w = (t) => {
161
+ let n = {
161
162
  errors: [],
162
163
  warnings: [],
163
164
  templates: []
164
165
  };
165
- if (!o(e)) return {
166
+ if (!e(t)) return {
166
167
  valid: !1,
167
168
  errors: [{
168
169
  path: "",
@@ -171,13 +172,13 @@ var r = [
171
172
  }],
172
173
  warnings: []
173
174
  };
174
- s(e.baseUrl) ? /^https?:\/\//.test(e.baseUrl) || d(t, "baseUrl", "Base URL must start with http:// or https://", "The engine resolves paths against it") : d(t, "baseUrl", "A connector needs a base URL", "The origin every endpoint path is appended to"), e.credential !== void 0 && typeof e.credential != "string" && d(t, "credential", "Must be the identifier of a stored credential", "The secret itself never goes here");
175
- let n = g(t, e.pagination, "pagination");
176
- return b(t, e.auth), p(t, e.headers, "headers", "request"), y(t, e.endpoints, n), x(t, e.operators), S(t, e.fields), e.media !== void 0 && (o(e.media) ? e.media.baseUrl !== void 0 && !s(e.media.baseUrl) && d(t, "media.baseUrl", "Must be a non-empty string", "The origin relative media paths are rebased onto") : d(t, "media", "Must be an object", "Shape: { baseUrl }")), e.projection !== void 0 && e.projection !== "full" && d(t, "projection", "The only projection is \"full\"", "Omit it to send only the paths the page binds"), C(t, e.credential), {
177
- valid: t.errors.length === 0,
178
- errors: t.errors,
179
- warnings: t.warnings
175
+ s(t.baseUrl) ? /^https?:\/\//.test(t.baseUrl) || d(n, "baseUrl", "Base URL must start with http:// or https://", "The engine resolves paths against it") : d(n, "baseUrl", "A connector needs a base URL", "The origin every endpoint path is appended to"), t.credential !== void 0 && typeof t.credential != "string" && d(n, "credential", "Must be the identifier of a stored credential", "The secret itself never goes here");
176
+ let r = g(n, t.pagination, "pagination");
177
+ return b(n, t.auth), p(n, t.headers, "headers", "request"), y(n, t.endpoints, r), x(n, t.operators), S(n, t.fields), t.media !== void 0 && (e(t.media) ? t.media.baseUrl !== void 0 && !s(t.media.baseUrl) && d(n, "media.baseUrl", "Must be a non-empty string", "The origin relative media paths are rebased onto") : d(n, "media", "Must be an object", "Shape: { baseUrl }")), t.projection !== void 0 && t.projection !== "full" && d(n, "projection", "The only projection is \"full\"", "Omit it to send only the paths the page binds"), C(n, t.credential), {
178
+ valid: n.errors.length === 0,
179
+ errors: n.errors,
180
+ warnings: n.warnings
180
181
  };
181
- };
182
+ }, T = (e) => w(e).valid;
182
183
  //#endregion
183
- export { w as validateConnectorManifest };
184
+ export { T as isConnectorManifestDraft, w as validateConnectorManifest };
@@ -1,45 +1,41 @@
1
- import { processTwigValue as e } from "../helpers/twigWrapper/processTwig/processTwig.mjs";
2
- import t from "@plitzi/plitzi-ui/utils/deepEqual";
1
+ import { isRecord as e } from "../helpers/isRecord.mjs";
2
+ import { processTwigValue as t } from "../helpers/twigWrapper/processTwig/processTwig.mjs";
3
+ import { COMPUTED_GLOBALS as n } from "./globalSources.mjs";
4
+ import r from "@plitzi/plitzi-ui/utils/deepEqual";
3
5
  //#region src/dataSource/computed.ts
4
- var n = (n, r, i) => {
5
- let a = {}, o = i !== void 0 && Object.keys(i).length === Object.keys(n).length;
6
- for (let [s, c] of Object.entries(n)) {
7
- let n = e(c, {
8
- ...r,
6
+ var i = (e, n, i) => {
7
+ let a = {}, o = i !== void 0 && Object.keys(i).length === Object.keys(e).length;
8
+ for (let [s, c] of Object.entries(e)) {
9
+ let e = t(c, {
10
+ ...n,
9
11
  computed: { ...a }
10
- }), l = i?.[s], u = i !== void 0 && Object.hasOwn(i, s) && (l === n || t(l, n));
11
- a[s] = u ? l : n, o &&= u;
12
+ }), l = i?.[s], u = i !== void 0 && Object.hasOwn(i, s) && (l === e || r(l, e));
13
+ a[s] = u ? l : e, o &&= u;
12
14
  }
13
15
  return o && i ? i : a;
14
- }, r = (e) => typeof e == "object" && !!e, i = (e) => r(e) && Object.values(e).every((e) => typeof e == "string"), a = [
15
- "variables",
16
- "navigation",
17
- "auth",
18
- "host",
19
- "theme"
20
- ], o = (e, t, n) => {
21
- let a = r(t) ? t : {};
22
- return i(n) ? {
23
- ...e,
24
- state: a,
25
- computed: c(n, e, a)
16
+ }, a = (t) => e(t) && Object.values(t).every((e) => typeof e == "string"), o = (t, n, r) => {
17
+ let i = e(n) ? n : {};
18
+ return a(r) ? {
19
+ ...t,
20
+ state: i,
21
+ computed: c(r, t, i)
26
22
  } : {
27
- ...e,
28
- state: a
23
+ ...t,
24
+ state: i
29
25
  };
30
26
  }, s, c = (e, t, r) => {
31
- let i = a.map((e) => t[e]);
32
- if (s?.definitions === e && s.state === r && s.globals.every((e, t) => e === i[t])) return s.computed;
33
- let o = n(e, {
34
- ...Object.fromEntries(a.map((e, t) => [e, i[t]])),
27
+ let a = n.map((e) => t[e]);
28
+ if (s?.definitions === e && s.state === r && s.globals.every((e, t) => e === a[t])) return s.computed;
29
+ let o = i(e, {
30
+ ...Object.fromEntries(n.map((e, t) => [e, a[t]])),
35
31
  state: r
36
32
  }, s?.definitions === e ? s.computed : void 0);
37
33
  return s = {
38
34
  definitions: e,
39
35
  state: r,
40
- globals: i,
36
+ globals: a,
41
37
  computed: o
42
38
  }, o;
43
39
  };
44
40
  //#endregion
45
- export { n as evaluateComputed, o as liveSources };
41
+ export { i as evaluateComputed, o as liveSources };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The data sources that belong to nobody: published once for the whole space by `GlobalSources`, and named as
3
+ * themselves rather than as `<type>_<id>` — which is what tells them apart from a source an element publishes.
4
+ *
5
+ * One list for everything that has to know them — the runtime evaluating computed values, the authoring validator
6
+ * refusing a binding to a name nothing answers to, an element that may not take one of these names as its id — so a
7
+ * new global is a global everywhere at once.
8
+ */
9
+ export declare const GLOBAL_SOURCES: readonly ["variables", "navigation", "auth", "state", "host", "theme", "flags", "computed"];
10
+ export type GlobalSource = (typeof GLOBAL_SOURCES)[number];
11
+ /**
12
+ * What a computed value is evaluated over: every global but `state`, which a flow hands it live, and `computed`, which
13
+ * is what is being evaluated.
14
+ */
15
+ export declare const COMPUTED_GLOBALS: ("auth" | "navigation" | "flags" | "variables" | "theme" | "host")[];
@@ -0,0 +1,13 @@
1
+ //#region src/dataSource/globalSources.ts
2
+ var e = [
3
+ "variables",
4
+ "navigation",
5
+ "auth",
6
+ "state",
7
+ "host",
8
+ "theme",
9
+ "flags",
10
+ "computed"
11
+ ], t = e.filter((e) => e !== "state" && e !== "computed");
12
+ //#endregion
13
+ export { t as COMPUTED_GLOBALS, e as GLOBAL_SOURCES };
@@ -1,6 +1,8 @@
1
1
  export * from './hooks';
2
2
  export * from './helpers';
3
3
  export { evaluateComputed, liveSources } from './computed';
4
+ export { GLOBAL_SOURCES, COMPUTED_GLOBALS } from './globalSources';
5
+ export type { GlobalSource } from './globalSources';
4
6
  export { default as getBindingsDetails } from './getBindingsDetails';
5
7
  export { default as resolveVariables } from './resolveVariables';
6
8
  export type { VariableScope } from './resolveVariables';
@@ -1,7 +1,8 @@
1
- import { evaluateComputed as e, liveSources as t } from "./computed.mjs";
2
- import n, { utilityOptions as r } from "./utility/index.mjs";
3
- import i from "./getBindingsDetails.mjs";
4
- import a from "./helpers/getSourceName.mjs";
5
- import o from "./hooks/useRegisterSource.mjs";
6
- import s from "./resolveVariables.mjs";
7
- export { e as evaluateComputed, i as getBindingsDetails, a as getSourceName, t as liveSources, s as resolveVariables, o as useRegisterSource, n as utility, r as utilityOptions };
1
+ import { COMPUTED_GLOBALS as e, GLOBAL_SOURCES as t } from "./globalSources.mjs";
2
+ import { evaluateComputed as n, liveSources as r } from "./computed.mjs";
3
+ import i, { utilityOptions as a } from "./utility/index.mjs";
4
+ import o from "./getBindingsDetails.mjs";
5
+ import s from "./helpers/getSourceName.mjs";
6
+ import c from "./hooks/useRegisterSource.mjs";
7
+ import l from "./resolveVariables.mjs";
8
+ export { e as COMPUTED_GLOBALS, t as GLOBAL_SOURCES, n as evaluateComputed, o as getBindingsDetails, s as getSourceName, r as liveSources, l as resolveVariables, c as useRegisterSource, i as utility, a as utilityOptions };
@@ -17,9 +17,18 @@ declare class PlitziConsole {
17
17
  listeningParams?: {
18
18
  category: Log['category'];
19
19
  };
20
+ recentLimit: number;
20
21
  constructor(callback?: CallbackInternal, pendingLimit?: number);
21
22
  setCallback(callback?: CallbackInternal): void;
22
23
  processPendingLogs(): void;
24
+ /**
25
+ * Every log as it is written, beside whatever panel takes them — what a reader in text (the agent inspector) keeps
26
+ * for itself. Only in a browser, as everything kept here is. `replay` hands it the last ones written first: the
27
+ * flows a page runs as it loads end before anything mounted later could have been listening.
28
+ */
29
+ addListener(listener: (log: Log) => void, { replay }?: {
30
+ replay?: boolean;
31
+ }): () => void;
23
32
  setCallbackAddProvider(callback?: CallbackAddProvider): void;
24
33
  setCallbackRemoveProvider(callback?: CallbackRemoveProvider): void;
25
34
  flush(hard?: boolean): void;
@@ -12,6 +12,9 @@ var e = (e, t = 2) => String(e).padStart(t, "0"), t = (t) => `${e(t.getHours())}
12
12
  listeningParams;
13
13
  #e = [];
14
14
  #t = !1;
15
+ #n = /* @__PURE__ */ new Set();
16
+ #r = [];
17
+ recentLimit = 200;
15
18
  constructor(e, t = 100) {
16
19
  this.callbackInternal = e, this.pendingLimit = t;
17
20
  }
@@ -24,6 +27,12 @@ var e = (e, t = 2) => String(e).padStart(t, "0"), t = (t) => `${e(t.getHours())}
24
27
  this.pendingLogs = [];
25
28
  }
26
29
  }
30
+ addListener(e, { replay: t = !1 } = {}) {
31
+ if (t) for (let t of this.#r) e(t);
32
+ return this.#n.add(e), () => {
33
+ this.#n.delete(e);
34
+ };
35
+ }
27
36
  setCallbackAddProvider(e) {
28
37
  this.callbackAddProvider = e;
29
38
  }
@@ -33,9 +42,20 @@ var e = (e, t = 2) => String(e).padStart(t, "0"), t = (t) => `${e(t.getHours())}
33
42
  flush(e = !1) {
34
43
  this.logsListened = [], e && (this.pendingLogs = []);
35
44
  }
36
- #n(e, t, r, i) {
45
+ #i(e, t, r, i) {
37
46
  if (!this.callbackInternal && !n()) return;
38
47
  let a = this.getTime(!0);
48
+ if (n()) {
49
+ let n = {
50
+ logType: e,
51
+ category: t,
52
+ message: r,
53
+ params: i,
54
+ time: a
55
+ };
56
+ this.#r.push(n), this.#r.length > this.recentLimit && this.#r.shift();
57
+ for (let e of this.#n) e(n);
58
+ }
39
59
  if (!this.callbackInternal) {
40
60
  this.pendingLogs.push({
41
61
  logType: e,
@@ -58,9 +78,9 @@ var e = (e, t = 2) => String(e).padStart(t, "0"), t = (t) => `${e(t.getHours())}
58
78
  message: r,
59
79
  params: i,
60
80
  time: a
61
- }), this.#r()), this.logsListened.length > this.logsListenedLimit && this.logsListened.shift();
81
+ }), this.#a()), this.logsListened.length > this.logsListenedLimit && this.logsListened.shift();
62
82
  }
63
- #r() {
83
+ #a() {
64
84
  this.#t || (this.#t = !0, queueMicrotask(() => {
65
85
  this.#t = !1;
66
86
  let e = this.callbackInternal, t = this.#e;
@@ -78,16 +98,16 @@ var e = (e, t = 2) => String(e).padStart(t, "0"), t = (t) => `${e(t.getHours())}
78
98
  return e ? t(n) : n;
79
99
  }
80
100
  info(e, t, n) {
81
- this.#n("info", e, t, n);
101
+ this.#i("info", e, t, n);
82
102
  }
83
103
  warning(e, t, n) {
84
- this.#n("warning", e, t, n);
104
+ this.#i("warning", e, t, n);
85
105
  }
86
106
  danger(e, t, n) {
87
- this.#n("danger", e, t, n);
107
+ this.#i("danger", e, t, n);
88
108
  }
89
109
  success(e, t, n) {
90
- this.#n("success", e, t, n);
110
+ this.#i("success", e, t, n);
91
111
  }
92
112
  begin(e) {
93
113
  this.listening = !0, this.listeningParams = { category: e };
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The cookie a tester forces flags with — the `qa` layer, the strongest there is.
3
+ *
4
+ * A cookie and not web storage for the reason the theme is one: the server renders with it, so the page a tester
5
+ * forced a flag on arrives drawn that way instead of being swapped after hydration. Named with the port, like the
6
+ * debug preference, because a cookie's scope has none (see `debugCookieName`).
7
+ *
8
+ * It is a preference that only means something where debugging is authorized. Everywhere else both halves ignore it
9
+ * — a published site's visitors could otherwise turn on any feature that is still behind a flag.
10
+ */
11
+ export declare const flagsCookieName: (host: string | undefined) => string;
12
+ /**
13
+ * `newCheckout:1,legacyNav:0` — a flag name and its value, nothing else survives the parse. The cookie's format, and
14
+ * any other place flags are written as one line of text (an environment variable).
15
+ */
16
+ export declare const parseFlagList: (value: string | undefined) => Record<string, boolean>;
17
+ export declare const serializeFlagList: (forced: Record<string, boolean>) => string;
18
+ /** What is forced once one flag is forced to `value` — or, with `undefined`, once it is no longer forced at all. */
19
+ export declare const withForcedFlag: (forced: Record<string, boolean>, name: string, value: boolean | undefined) => Record<string, boolean>;
20
+ /** The flags a tester forced, from a `Cookie` header or `document.cookie`. */
21
+ export declare const forcedFlagsFromCookies: (cookies: string | undefined, host: string | undefined) => Record<string, boolean>;
22
+ /**
23
+ * Keeps what a tester forced for the next page this browser asks for — every page of the site, so a forced feature is
24
+ * on wherever the tester goes, and the server draws it that way. Nothing forced removes the cookie.
25
+ */
26
+ export declare const writeForcedFlags: (host: string, forced: Record<string, boolean>) => void;
@@ -0,0 +1,20 @@
1
+ import { cookieFromHeader as e } from "../helpers/cookies.mjs";
2
+ import { isFlagName as t } from "./schemaFlag.mjs";
3
+ //#region src/flags/flagsCookie.ts
4
+ var n = (e) => {
5
+ let t = e?.split(":")[1];
6
+ return t ? `plitzi_flags_${t}` : "plitzi_flags";
7
+ }, r = (e) => e ? Object.fromEntries(e.split(",").map((e) => e.split(":")).filter(([e, n]) => t(e) && (n === "1" || n === "0")).map(([e, t]) => [e, t === "1"])) : {}, i = (e) => Object.entries(e).filter(([e]) => t(e)).map(([e, t]) => `${e}:${t ? "1" : "0"}`).join(","), a = (e, t, n) => {
8
+ let { [t]: r, ...i } = e;
9
+ return n === void 0 ? i : {
10
+ ...i,
11
+ [t]: n
12
+ };
13
+ }, o = (t, i) => r(e(t, n(i))), s = (e, t) => {
14
+ let r = n(e), a = i(t);
15
+ try {
16
+ document.cookie = a ? `${r}=${encodeURIComponent(a)};path=/;SameSite=Lax` : `${r}=;path=/;max-age=0;SameSite=Lax`;
17
+ } catch {}
18
+ };
19
+ //#endregion
20
+ export { n as flagsCookieName, o as forcedFlagsFromCookies, r as parseFlagList, i as serializeFlagList, a as withForcedFlag, s as writeForcedFlags };
@@ -0,0 +1,3 @@
1
+ export * from './schemaFlag';
2
+ export * from './resolveFlags';
3
+ export * from './flagsCookie';
@@ -0,0 +1,4 @@
1
+ import { FLAG_GATE_PATTERN as e, FLAG_NAME_PATTERN as t, isFlagName as n, isSchemaFlag as r } from "./schemaFlag.mjs";
2
+ import { flagsCookieName as i, forcedFlagsFromCookies as a, parseFlagList as o, serializeFlagList as s, withForcedFlag as c, writeForcedFlags as l } from "./flagsCookie.mjs";
3
+ import { FLAG_LAYERS as u, flagUserFromSSR as d, flagValues as f, hasConditions as p, passesFlagGate as m, resolveFlags as h, undeclaredFlagOverrides as g } from "./resolveFlags.mjs";
4
+ export { e as FLAG_GATE_PATTERN, u as FLAG_LAYERS, t as FLAG_NAME_PATTERN, d as flagUserFromSSR, f as flagValues, i as flagsCookieName, a as forcedFlagsFromCookies, p as hasConditions, n as isFlagName, r as isSchemaFlag, o as parseFlagList, m as passesFlagGate, h as resolveFlags, s as serializeFlagList, g as undeclaredFlagOverrides, c as withForcedFlag, l as writeForcedFlags };
@@ -0,0 +1,60 @@
1
+ import { VariableScope } from '../dataSource/resolveVariables';
2
+ import { RuleGroup } from '../helpers/ruleEvaluator';
3
+ import { Schema, SSRUser } from '../types';
4
+ /**
5
+ * Who decided a flag, weakest first: the space's own declaration, then the server rendering it, then the SDK
6
+ * embedding it, then a tester with the dev tools open. Each layer only ever answers for a flag the space declares.
7
+ */
8
+ export declare const FLAG_LAYERS: readonly ["space", "server", "sdk", "qa"];
9
+ export type FlagLayer = (typeof FLAG_LAYERS)[number];
10
+ export type FlagOverrideLayer = Exclude<FlagLayer, 'space'>;
11
+ /** What each layer above the space says, by flag name. A layer that says nothing about a flag leaves it alone. */
12
+ export type FlagOverrides = Partial<Record<FlagOverrideLayer, Record<string, boolean>>>;
13
+ /** The visitor, as a flag's rule sees them: never a token, never anything the rules have no business matching on. */
14
+ export type FlagUser = {
15
+ authenticated: boolean;
16
+ email?: string;
17
+ username?: string;
18
+ roles?: string[];
19
+ };
20
+ /** The visitor a server resolved, as a flag's rule sees them — the same fields the browser's rules see. */
21
+ export declare const flagUserFromSSR: (user: Pick<SSRUser, "email" | "username" | "roles"> | undefined) => FlagUser;
22
+ /** What a flag's rules are matched against: everything a variable's are, and who is visiting. */
23
+ export type FlagScope = VariableScope & {
24
+ user?: FlagUser;
25
+ };
26
+ /**
27
+ * One flag's answer, and where it came from: the layer that decided, and — when the space did — the index of the
28
+ * rule that matched, absent when it was the flag's own default. What the dev tools show beside the value.
29
+ */
30
+ export type FlagResolution = {
31
+ value: boolean;
32
+ layer: FlagLayer;
33
+ rule?: number;
34
+ };
35
+ /**
36
+ * Whether a rule says anything at all. A rule just added in the builder has an empty group, and the evaluator reads
37
+ * an empty `and` as true — so an unfinished rule would turn the flag the moment it was added. It is skipped instead,
38
+ * and the linter says it is there.
39
+ */
40
+ export declare const hasConditions: (when: unknown) => when is RuleGroup;
41
+ /**
42
+ * Every flag the space declares, resolved for this render: `{ newCheckout: { value: true, layer: 'space', rule: 0 } }`.
43
+ *
44
+ * The space answers first — the first of a flag's rules that matches, or its default — and each layer above it may
45
+ * replace that answer, in order. An override for a flag the space does not declare is not an answer to anything and
46
+ * is dropped here; {@link undeclaredFlagOverrides} names those so whoever set one can be told.
47
+ */
48
+ export declare const resolveFlags: (declared: Schema["flags"], scope?: FlagScope, overrides?: FlagOverrides) => Record<string, FlagResolution>;
49
+ /** The answers alone, as the `flags` source publishes them: `{ newCheckout: true }`. */
50
+ export declare const flagValues: (resolutions: Record<string, FlagResolution>) => Record<string, boolean>;
51
+ /** Overrides naming a flag the space does not declare — each one a typo or a flag removed from the space. */
52
+ export declare const undeclaredFlagOverrides: (declared: Schema["flags"], overrides: FlagOverrides) => {
53
+ layer: FlagOverrideLayer;
54
+ name: string;
55
+ }[];
56
+ /** Whether a flag gate lets its element exist, given the flags as they resolved. An undeclared flag resolves off. */
57
+ export declare const passesFlagGate: (gate: {
58
+ name: string;
59
+ is: boolean;
60
+ } | undefined, values: Record<string, boolean>) => boolean;