@k2b/cloud 0.40.0 → 0.42.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 (279) hide show
  1. package/package.json +9 -5
  2. package/src/_internal/bounded-json.ts +14 -2
  3. package/src/_internal/capabilities.ts +87 -8
  4. package/src/_internal/capability-reviews.ts +6 -0
  5. package/src/_internal/capability-sentences.ts +2 -1
  6. package/src/_internal/capability-timeout.ts +71 -0
  7. package/src/_internal/define-app.ts +158 -92
  8. package/src/_internal/heartbeat.ts +203 -14
  9. package/src/_internal/http-drain.ts +56 -0
  10. package/src/_internal/registry-validation.ts +3 -0
  11. package/src/_internal/registry.ts +28 -1
  12. package/src/_internal/runtime-context.ts +1 -0
  13. package/src/_internal/setup-lock.ts +103 -0
  14. package/src/_internal/status-preserving-ssr.ts +2 -0
  15. package/src/access/PermissionEditor.tsx +16 -17
  16. package/src/access/PrincipalPicker.tsx +45 -10
  17. package/src/access/messages.ts +8 -0
  18. package/src/access/principal-label.ts +18 -0
  19. package/src/access/ui.ts +1 -0
  20. package/src/account/EntitySearch.tsx +5 -4
  21. package/src/ai/action-review.ts +2 -1
  22. package/src/ai/app-skill-store.ts +1 -1
  23. package/src/ai/capabilities.ts +21 -3
  24. package/src/ai/capability-execution.ts +14 -12
  25. package/src/ai/chat/action-card.ts +76 -4
  26. package/src/ai/chat/action-messages.ts +14 -0
  27. package/src/ai/chat/action-question.browser-harness.tsx +12 -0
  28. package/src/ai/chat/action-question.tsx +214 -23
  29. package/src/ai/chat/action-text.ts +288 -0
  30. package/src/ai/chat/tool-action-words.ts +31 -0
  31. package/src/ai/chat/tool-action.tsx +1 -26
  32. package/src/ai/chat-tasks.ts +2 -1
  33. package/src/ai/client/controller.ts +150 -32
  34. package/src/ai/client/transport.ts +14 -2
  35. package/src/ai/code-capability-routes.ts +27 -23
  36. package/src/ai/code-runtime-tools.ts +14 -16
  37. package/src/ai/code-source-tools.ts +16 -18
  38. package/src/ai/executor.ts +64 -21
  39. package/src/ai/fetch-file-tool.ts +67 -76
  40. package/src/ai/firecrawl-tools.ts +15 -2
  41. package/src/ai/http.ts +1 -0
  42. package/src/ai/index.ts +1 -0
  43. package/src/ai/migrate.ts +28 -0
  44. package/src/ai/open-questions.ts +168 -0
  45. package/src/ai/projects.ts +1 -2
  46. package/src/ai/protocol.ts +2 -2
  47. package/src/ai/question-text.ts +8 -0
  48. package/src/ai/recent-resources.ts +12 -5
  49. package/src/ai/review-content.ts +77 -0
  50. package/src/ai/routes.ts +119 -35
  51. package/src/ai/runtime.ts +1 -0
  52. package/src/ai/skill-tool.ts +17 -6
  53. package/src/ai/skills-routes.ts +72 -27
  54. package/src/ai/skills.ts +139 -60
  55. package/src/ai/store.ts +184 -31
  56. package/src/ai/testing.ts +36 -0
  57. package/src/ai/tool-sentences.ts +152 -34
  58. package/src/ai/tool-wording.ts +12 -6
  59. package/src/ai/tools.ts +8 -3
  60. package/src/ai/types.ts +25 -4
  61. package/src/ai/usage.ts +2 -2
  62. package/src/api/admin-core-settings.ts +15 -2
  63. package/src/api/admin-geo.ts +54 -0
  64. package/src/api/admin-linux-identities.ts +6 -3
  65. package/src/api/admin-outgoing-mail.ts +29 -15
  66. package/src/api/app-approval-actions.ts +31 -7
  67. package/src/api/approvals-loader.ts +3 -3
  68. package/src/api/approvals.ts +51 -0
  69. package/src/api/apps.ts +4 -2
  70. package/src/api/auth/schemas.ts +3 -0
  71. package/src/api/auth.ts +54 -18
  72. package/src/api/capabilities.ts +258 -181
  73. package/src/api/capability-streams.ts +21 -13
  74. package/src/api/cli-plugins.ts +4 -1
  75. package/src/api/geo-glyphs.ts +11 -0
  76. package/src/api/geo.ts +128 -0
  77. package/src/api/help.ts +12 -4
  78. package/src/api/index.ts +5 -0
  79. package/src/api/mcp.ts +73 -41
  80. package/src/api/me-panel-consent.ts +8 -5
  81. package/src/api/me.ts +79 -3
  82. package/src/api/search.ts +21 -14
  83. package/src/api/sync-ops.ts +19 -13
  84. package/src/api/widgets.ts +42 -18
  85. package/src/approvals/Approvals.tsx +30 -66
  86. package/src/approvals/approval-card.ts +68 -0
  87. package/src/browser/CloudResourceSearch.browser-harness.tsx +53 -1
  88. package/src/browser/CloudResourceSearch.tsx +3 -13
  89. package/src/browser/PanelLeaveNotice.tsx +18 -0
  90. package/src/browser/navigation-search.ts +78 -25
  91. package/src/browser/panel-leave.ts +69 -0
  92. package/src/browser/panel-messages.ts +12 -0
  93. package/src/browser/panel-slot.ts +173 -24
  94. package/src/browser/panel.ts +3 -0
  95. package/src/browser/resource-search-messages.ts +2 -0
  96. package/src/capabilities/client.ts +28 -1
  97. package/src/capabilities/executions.ts +22 -3
  98. package/src/capabilities/geo-client.ts +57 -0
  99. package/src/capabilities/response.ts +2 -1
  100. package/src/capabilities/review-storage.ts +24 -0
  101. package/src/capabilities/reviews.ts +17 -3
  102. package/src/capabilities/server.ts +36 -16
  103. package/src/cli/access.ts +15 -23
  104. package/src/cli/admin/linux.ts +13 -2
  105. package/src/cli/admin/outgoing-mail.ts +26 -4
  106. package/src/cli/capabilities.ts +19 -0
  107. package/src/config/env.ts +0 -6
  108. package/src/contracts/app-access.ts +48 -0
  109. package/src/contracts/app-approval.ts +3 -3
  110. package/src/contracts/app.ts +4 -1
  111. package/src/contracts/approvals.ts +2 -2
  112. package/src/contracts/avatar.ts +186 -0
  113. package/src/contracts/capabilities.ts +149 -55
  114. package/src/contracts/geo-admin.ts +127 -0
  115. package/src/contracts/geo-map.ts +19 -0
  116. package/src/contracts/geo-route.ts +168 -0
  117. package/src/contracts/geo.ts +248 -0
  118. package/src/contracts/index.ts +4 -0
  119. package/src/contracts/outgoing-mail.ts +17 -4
  120. package/src/contracts/registry.ts +2 -0
  121. package/src/contracts/shared.ts +3 -0
  122. package/src/events/app-access.ts +68 -0
  123. package/src/events/live-delivery.ts +128 -0
  124. package/src/events/live.ts +14 -130
  125. package/src/geo/CloudMap.tsx +95 -0
  126. package/src/geo/map-messages.ts +17 -0
  127. package/src/geo/ui.ts +1 -0
  128. package/src/index.ts +2 -0
  129. package/src/server/client-ip.ts +36 -0
  130. package/src/server/index.ts +3 -4
  131. package/src/server/middleware/app-access.ts +312 -0
  132. package/src/server/middleware/auth.ts +5 -3
  133. package/src/server/middleware/invocation.ts +11 -0
  134. package/src/server/middleware/rate-limit.ts +4 -4
  135. package/src/server/services/access.ts +13 -9
  136. package/src/server/services/index.ts +0 -2
  137. package/src/server/services/services.ts +0 -2
  138. package/src/services/accounts/app.ts +23 -3
  139. package/src/services/accounts/posix.ts +21 -7
  140. package/src/services/accounts/users.ts +12 -1
  141. package/src/services/allowed-network-fetch.ts +16 -10
  142. package/src/services/app-access-metrics.ts +24 -0
  143. package/src/services/app-access.ts +123 -0
  144. package/src/services/app-discovery.ts +27 -0
  145. package/src/services/approvals/content.ts +40 -0
  146. package/src/services/approvals/device.ts +49 -33
  147. package/src/services/approvals/index.ts +15 -6
  148. package/src/services/approvals/list.ts +6 -11
  149. package/src/services/approvals/question.ts +72 -0
  150. package/src/services/audit/index.ts +1 -0
  151. package/src/services/auth-flows/ipa.ts +39 -2
  152. package/src/services/auth-flows/password-reset.ts +32 -6
  153. package/src/services/downstream-budget.ts +87 -0
  154. package/src/services/geo/admin.ts +262 -0
  155. package/src/services/geo/bucket.ts +67 -0
  156. package/src/services/geo/cache.ts +57 -0
  157. package/src/services/geo/costs.ts +5 -0
  158. package/src/services/geo/errors.ts +41 -0
  159. package/src/services/geo/fixtures/README.md +17 -0
  160. package/src/services/geo/fixtures/along.json +355 -0
  161. package/src/services/geo/fixtures/autocomplete.json +218 -0
  162. package/src/services/geo/fixtures/geocode.json +129 -0
  163. package/src/services/geo/fixtures/places.json +355 -0
  164. package/src/services/geo/fixtures/reverse.json +61 -0
  165. package/src/services/geo/fixtures/routing.json +57 -0
  166. package/src/services/geo/geoapify-route.ts +93 -0
  167. package/src/services/geo/geoapify.ts +281 -0
  168. package/src/services/geo/ledger.ts +122 -0
  169. package/src/services/geo/map.ts +160 -0
  170. package/src/services/geo/migrate.ts +25 -0
  171. package/src/services/geo/polyline.ts +184 -0
  172. package/src/services/geo/route-chain.ts +145 -0
  173. package/src/services/geo/route-costs.ts +9 -0
  174. package/src/services/geo/route-geometry.ts +39 -0
  175. package/src/services/geo/route-plan.ts +172 -0
  176. package/src/services/geo/route-service.ts +433 -0
  177. package/src/services/geo/service.ts +300 -0
  178. package/src/services/geo/settings.ts +49 -0
  179. package/src/services/help/index.ts +16 -7
  180. package/src/services/help/types.ts +6 -1
  181. package/src/services/identity/invocation-actor.ts +20 -2
  182. package/src/services/identity/issue-invocation.ts +67 -0
  183. package/src/services/identity/key-ring.ts +5 -3
  184. package/src/services/identity/runtime-config.ts +23 -0
  185. package/src/services/index.ts +11 -0
  186. package/src/services/mandates/index.ts +40 -3
  187. package/src/services/network-security.ts +6 -3
  188. package/src/services/network-transport.ts +99 -0
  189. package/src/services/notifications/catalog.ts +3 -2
  190. package/src/services/notifications/runtime.ts +1 -0
  191. package/src/services/notifications/web-push-transport.ts +45 -38
  192. package/src/services/outgoing-mail/dispatcher.ts +6 -1
  193. package/src/services/outgoing-mail/index.ts +55 -1
  194. package/src/services/outgoing-mail/messages.ts +82 -3
  195. package/src/services/outgoing-mail/resolve-host.ts +2 -2
  196. package/src/services/outgoing-mail/retention.ts +13 -1
  197. package/src/services/outgoing-mail/store.ts +36 -6
  198. package/src/services/outgoing-mail/test-send.ts +34 -4
  199. package/src/services/outgoing-mail/transport.ts +1 -1
  200. package/src/services/pdf/gotenberg.ts +11 -38
  201. package/src/services/pdf/markdown.ts +160 -2
  202. package/src/services/pdf/template-preview.ts +1 -1
  203. package/src/services/public-http.ts +28 -40
  204. package/src/services/session/index.ts +203 -29
  205. package/src/services/settings/app.ts +4 -1
  206. package/src/services/settings/core-settings.ts +88 -0
  207. package/src/services/settings/defaults.ts +8 -2
  208. package/src/services/settings/errors.ts +11 -0
  209. package/src/services/settings/geo-budget.ts +40 -0
  210. package/src/services/settings/index.ts +4 -3
  211. package/src/services/settings/store.ts +25 -17
  212. package/src/services/weather/geo.ts +29 -111
  213. package/src/services/weather/index.ts +4 -3
  214. package/src/services/weather/locations.ts +8 -5
  215. package/src/services/weather/migrate.ts +1 -0
  216. package/src/services/weather/settings.ts +0 -16
  217. package/src/shared/__snapshots__/avatar-art.test.ts.snap +5 -0
  218. package/src/shared/avatar-art.ts +400 -0
  219. package/src/shared/index.ts +2 -0
  220. package/src/shared/network-address.ts +22 -3
  221. package/src/shared/template-rendering.ts +36 -4
  222. package/src/shared-text/documents.ts +1 -1
  223. package/src/shared-text/index.ts +2 -0
  224. package/src/shared-text/log.ts +51 -3
  225. package/src/shared-text/snapshots.ts +340 -0
  226. package/src/ssr/AdminLayout.tsx +4 -2
  227. package/src/ssr/CloudShell.island.tsx +6 -0
  228. package/src/ssr/HelpPanelArticle.island.tsx +308 -0
  229. package/src/ssr/HelpPanelBack.island.tsx +32 -0
  230. package/src/ssr/HelpPanelMenu.island.tsx +133 -0
  231. package/src/ssr/HelpPanelSearch.island.tsx +123 -0
  232. package/src/ssr/HelpPanelShortcuts.island.tsx +22 -0
  233. package/src/ssr/HelpPanelView.island.tsx +27 -0
  234. package/src/ssr/Layout.tsx +65 -15
  235. package/src/ssr/LayoutHelp.browser-harness.tsx +1 -1
  236. package/src/ssr/LayoutHelp.tsx +185 -542
  237. package/src/ssr/LayoutHelpPanel.browser-harness.tsx +6 -7
  238. package/src/ssr/LayoutHelpPanel.server.browser-harness.tsx +131 -0
  239. package/src/ssr/LayoutHelpPanel.server.tsx +115 -0
  240. package/src/ssr/PanelRuntime.island.tsx +11 -7
  241. package/src/ssr/PwaLayout.tsx +2 -2
  242. package/src/ssr/RailApps.tsx +6 -0
  243. package/src/ssr/ShellRuntime.island.tsx +23 -7
  244. package/src/ssr/__snapshots__/Layout.unchanged.render.test.tsx.snap +151 -0
  245. package/src/ssr/__snapshots__/LayoutHelp.ssr.render.test.tsx.snap +29 -0
  246. package/src/ssr/admin-navigation.ts +1 -0
  247. package/src/ssr/app-badges.ts +6 -1
  248. package/src/ssr/compact-shell.browser-harness.ts +44 -5
  249. package/src/ssr/help.ts +7 -5
  250. package/src/ssr/index.ts +2 -1
  251. package/src/ssr/islands/index.ts +3 -4
  252. package/src/ssr/layout-context.ts +2 -0
  253. package/src/ssr/layout-help-panel-controls.tsx +43 -0
  254. package/src/ssr/layout-help-panel-document.ts +67 -0
  255. package/src/ssr/layout-help-panel-lifecycle.ts +32 -0
  256. package/src/ssr/layout-help-panel-menu.tsx +113 -0
  257. package/src/ssr/layout-help-panel-modules.ts +7 -0
  258. package/src/ssr/layout-help-panel-reader.tsx +159 -0
  259. package/src/ssr/layout-help-panel-search.tsx +69 -0
  260. package/src/ssr/layout-help-panel-shortcuts.ts +7 -0
  261. package/src/ssr/layout-help-panel-state.ts +141 -0
  262. package/src/ssr/layout-help-panel-types.ts +19 -0
  263. package/src/ssr/layout-help-views.tsx +484 -0
  264. package/src/ssr/mobile-menu-history.ts +4 -0
  265. package/src/ssr/page-swap-fixture/Column.island.tsx +15 -0
  266. package/src/ssr/page-swap-fixture/ProviderProbe.island.tsx +31 -0
  267. package/src/ssr/page-swap.browser-harness.tsx +177 -0
  268. package/src/ssr/page-swap.ts +28 -0
  269. package/src/ssr/page-trail-runtime.ts +32 -13
  270. package/src/ssr/panel-consent.ts +2 -2
  271. package/src/ssr/panel-idle.ts +9 -0
  272. package/src/ssr/panel-slot.browser-harness.tsx +3 -0
  273. package/src/ssr/platform-messages.ts +8 -0
  274. package/src/ssr/runtime.ts +17 -0
  275. package/src/ssr/shell-data.tsx +10 -2
  276. package/src/styles/approvals.css +6 -0
  277. package/src/styles/effects.css +15 -0
  278. package/src/styles/global.css +70 -6
  279. package/src/server/services/geo.ts +0 -215
@@ -1,123 +1,41 @@
1
- import { err, fail, ok, type PageParams, type Paginated, type Result } from "@k2b/stdlib";
2
- import { type GeoPlace, geoService } from "../../server";
3
- import * as settings from "../settings";
1
+ import { err, fail, ok, type PageParams } from "@k2b/stdlib";
2
+ import { geoClient } from "../../capabilities/geo-client";
3
+ import type { CapabilityCaller } from "../../capabilities/server";
4
+ import type { GeoProvenance } from "../../contracts/geo";
4
5
 
5
6
  export const WEATHER_COUNTRY_CODE = "DE";
7
+ export type WeatherCity = { name: string; lat: number; lon: number; country?: string; state?: string; provenance: GeoProvenance };
6
8
 
7
- export type WeatherCity = {
8
- name: string;
9
- lat: number;
10
- lon: number;
11
- country?: string;
12
- state?: string;
13
- };
14
-
15
- const unavailable = <T>(): Result<T> =>
16
- fail({
17
- code: "WEATHER_CITY_SEARCH_UNAVAILABLE",
18
- message: "Weather city search is unavailable",
19
- status: 500,
20
- });
21
-
22
- /**
23
- * Adapts generic geo place data to the weather app's city model.
24
- */
25
- const mapPlace = (place: GeoPlace): WeatherCity => ({
26
- name: place.name,
27
- lat: place.lat,
28
- lon: place.lon,
29
- country: place.country,
30
- state: place.state,
31
- });
32
-
33
- /**
34
- * Resolves and validates the configured geo service base URL.
35
- */
36
- const getGeoBaseUrl = async (): Promise<Result<string>> => {
37
- const geoUrl = (await settings.get<string>("weather.geo_url")).trim();
38
- if (!geoUrl) {
39
- return fail({
40
- code: "WEATHER_CITY_SEARCH_NOT_CONFIGURED",
41
- message: "Geo API URL is not configured. Set weather.geo_url.",
42
- status: 500,
43
- });
44
- }
45
- return ok(geoUrl.replace(/\/$/, ""));
46
- };
47
-
48
- /**
49
- * Searches city candidates via the geo backend and enforces weather-specific country constraints.
50
- */
9
+ /** Weather adapts Core's public address contract; only Core owns provider access and budgets. */
51
10
  const list = async (config: {
11
+ caller: CapabilityCaller;
52
12
  pagination?: PageParams;
53
13
  signal?: AbortSignal;
54
- filter: {
55
- query: string;
56
- country?: string;
57
- };
58
- }): Promise<Result<Paginated<WeatherCity>>> => {
14
+ filter: { query: string; country?: string };
15
+ }) => {
59
16
  const query = config.filter.query.trim();
60
- if (!query) {
61
- return ok({
62
- items: [],
63
- page: config.pagination?.page ?? 1,
64
- perPage: config.pagination?.perPage ?? 20,
65
- total: 0,
66
- hasNext: false,
67
- });
68
- }
69
-
70
- const requestedCountry = config.filter.country?.trim().toUpperCase() ?? WEATHER_COUNTRY_CODE;
71
- if (requestedCountry !== WEATHER_COUNTRY_CODE) {
17
+ const page = config.pagination?.page ?? 1;
18
+ const perPage = Math.min(5, config.pagination?.perPage ?? 5);
19
+ if ((config.filter.country?.trim().toUpperCase() ?? WEATHER_COUNTRY_CODE) !== WEATHER_COUNTRY_CODE)
72
20
  return fail(err.badInput("Only German city search is supported (country=DE)."));
73
- }
74
-
75
- const baseUrlResult = await getGeoBaseUrl();
76
- if (!baseUrlResult.ok) return baseUrlResult;
77
- const geoUrl = baseUrlResult.data;
78
- const result = await geoService.place.list({
79
- baseUrl: geoUrl,
80
- pagination: config.pagination,
81
- signal: config.signal,
82
- filter: {
83
- query,
84
- country: WEATHER_COUNTRY_CODE,
85
- featureClass: "P",
21
+ if (query.length < 3 || page > 1) return ok({ items: [], page, perPage, total: 0, hasNext: false });
22
+ const result = await geoClient.autocomplete(
23
+ { text: query, countryCode: WEATHER_COUNTRY_CODE, type: "city", limit: perPage },
24
+ {
25
+ ...config.caller,
26
+ signal: config.signal ?? config.caller.signal,
86
27
  },
87
- });
88
- if (!result.ok) return unavailable();
89
-
90
- return ok({
91
- ...result.data,
92
- items: result.data.items.map(mapPlace),
93
- });
94
- };
95
-
96
- /**
97
- * Resolves one place by coordinates via the geo backend.
98
- */
99
- const get = async (config: { lat: number; lon: number }): Promise<Result<WeatherCity | null>> => {
100
- const baseUrlResult = await getGeoBaseUrl();
101
- if (!baseUrlResult.ok) return baseUrlResult;
102
- const result = await geoService.place.get({
103
- baseUrl: baseUrlResult.data,
104
- lat: config.lat,
105
- lon: config.lon,
106
- });
28
+ );
107
29
  if (!result.ok) return result;
108
-
109
- const place = result.data;
110
- if (!place) return ok(null);
111
- if (place.featureClass !== undefined && place.featureClass !== "P") {
112
- return ok(null);
113
- }
114
-
115
- return ok(mapPlace(place));
116
- };
117
-
118
- export const weatherCityService = {
119
- list,
120
- get,
30
+ const items = result.data.data.suggestions.map((address) => ({
31
+ name: address.city || address.formatted,
32
+ lat: address.point.lat,
33
+ lon: address.point.lon,
34
+ country: address.countryCode,
35
+ provenance: address.provenance,
36
+ ...(address.stateRegion ? { state: address.stateRegion } : {}),
37
+ }));
38
+ return ok({ items, page, perPage, total: items.length, hasNext: false });
121
39
  };
122
-
40
+ export const weatherCityService = { list };
123
41
  export type WeatherCityService = typeof weatherCityService;
@@ -1,11 +1,11 @@
1
- import { err, fail, ok, type Result } from "@k2b/stdlib";
1
+ import { err, fail, ok } from "@k2b/stdlib";
2
+ import type { CapabilityCaller } from "../../capabilities/server";
2
3
  import { registerSettings, toLegacySettingDefs } from "../settings/defaults";
3
4
  import { getCurrentWeather, getWeatherData } from "./forecast";
4
5
  import { WEATHER_COUNTRY_CODE } from "./geo";
5
6
  import { weatherLocationService } from "./location";
6
7
  import { weatherLocationsService } from "./locations";
7
8
  import { WEATHER_SETTINGS } from "./settings";
8
- import type { WeatherData } from "./types";
9
9
  import { weatherUiService } from "./ui";
10
10
 
11
11
  registerSettings(toLegacySettingDefs(WEATHER_SETTINGS));
@@ -13,13 +13,14 @@ registerSettings(toLegacySettingDefs(WEATHER_SETTINGS));
13
13
  /**
14
14
  * Resolves a city name to coordinates and returns weather for the first match.
15
15
  */
16
- const getByCityName = async (config: { query: string }): Promise<Result<WeatherData>> => {
16
+ const getByCityName = async (config: { query: string; caller: CapabilityCaller }) => {
17
17
  const query = config.query.trim();
18
18
  if (!query) {
19
19
  return fail(err.badInput("City query is required"));
20
20
  }
21
21
 
22
22
  const cityResult = await weatherLocationService.city.list({
23
+ caller: config.caller,
23
24
  pagination: { page: 1, perPage: 1 },
24
25
  filter: {
25
26
  query,
@@ -1,5 +1,6 @@
1
1
  import { err, fail, ok, type PageParams, type Paginated, paginate, type Result } from "@k2b/stdlib";
2
2
  import { sql } from "bun";
3
+ import type { GeoProvenance } from "../../contracts/geo";
3
4
  import { logger } from "../logging";
4
5
  import { withWeatherLocationShortId } from "./short-id";
5
6
 
@@ -11,6 +12,7 @@ export type Location = {
11
12
  state: string | null;
12
13
  lat: number;
13
14
  lon: number;
15
+ provenance?: GeoProvenance | null;
14
16
  };
15
17
 
16
18
  /**
@@ -23,6 +25,7 @@ const create = async (config: {
23
25
  state?: string;
24
26
  lat: number;
25
27
  lon: number;
28
+ provenance?: GeoProvenance;
26
29
  };
27
30
  }): Promise<Result<Location>> => {
28
31
  try {
@@ -30,10 +33,10 @@ const create = async (config: {
30
33
  await tx`SELECT pg_advisory_xact_lock(hashtext('cloud.weather.location-short-id-backfill'))`;
31
34
  return withWeatherLocationShortId(async (shortId) => {
32
35
  const [row] = await tx`
33
- INSERT INTO weather_locations (short_id, user_id, name, state, lat, lon)
34
- VALUES (${shortId}, ${config.userId}, ${config.data.name}, ${config.data.state ?? null}, ${config.data.lat}, ${config.data.lon})
36
+ INSERT INTO weather_locations (short_id, user_id, name, state, lat, lon, provenance)
37
+ VALUES (${shortId}, ${config.userId}, ${config.data.name}, ${config.data.state ?? null}, ${config.data.lat}, ${config.data.lon}, (${config.data.provenance ? JSON.stringify(config.data.provenance) : null}::text)::jsonb)
35
38
  ON CONFLICT (short_id) DO NOTHING
36
- RETURNING short_id AS id, name, state, lat, lon
39
+ RETURNING short_id AS id, name, state, lat, lon, provenance
37
40
  `;
38
41
  return (row as Location | undefined) ?? null;
39
42
  });
@@ -93,7 +96,7 @@ const list = async (config: { userId: string; pagination?: PageParams; filter?:
93
96
  `;
94
97
 
95
98
  const items = (await sql`
96
- SELECT short_id AS id, name, state, lat, lon
99
+ SELECT short_id AS id, name, state, lat, lon, provenance
97
100
  FROM weather_locations
98
101
  WHERE user_id = ${config.userId}
99
102
  AND ${queryMatch}
@@ -118,7 +121,7 @@ const list = async (config: { userId: string; pagination?: PageParams; filter?:
118
121
  */
119
122
  const get = async (config: { id: string; userId: string }): Promise<Location | null> => {
120
123
  const [location] = await sql`
121
- SELECT short_id AS id, name, state, lat, lon
124
+ SELECT short_id AS id, name, state, lat, lon, provenance
122
125
  FROM weather_locations
123
126
  WHERE short_id = ${config.id} AND user_id = ${config.userId}
124
127
  `;
@@ -14,6 +14,7 @@ export const migrate = async (): Promise<void> => {
14
14
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
15
15
  )
16
16
  `.simple();
17
+ await sql`ALTER TABLE weather_locations ADD COLUMN IF NOT EXISTS provenance JSONB`.simple();
17
18
  console.log(" ✓ weather_locations table");
18
19
 
19
20
  await sql`ALTER TABLE weather_locations ADD COLUMN IF NOT EXISTS short_id TEXT`.simple();
@@ -47,20 +47,4 @@ export const WEATHER_SETTINGS = {
47
47
  },
48
48
  },
49
49
  },
50
- "weather.geo_url": {
51
- kind: "url",
52
- label: "Geo API URL",
53
- default: "",
54
- description: "Geocoding API URL for the location search feature",
55
- placeholder: "e.g. https://geocoding.example.com/search",
56
- presentation: {
57
- translations: {
58
- de: {
59
- label: "Geo-API-URL",
60
- description: "Geocoding-API-URL für die Ortssuche",
61
- placeholder: "z. B. https://geocoding.example.com/search",
62
- },
63
- },
64
- },
65
- },
66
50
  } as const;
@@ -0,0 +1,5 @@
1
+ // Bun Snapshot v1, https://bun.sh/docs/test/snapshots
2
+
3
+ exports[`rendering keeps rendering a stored version 1 config byte for byte 1`] = `"7ac4c8231955f18292bccc1574886dff7fafb1453d6cbaf6d58f02452b65c4ff"`;
4
+
5
+ exports[`rendering keeps rendering a stored version 1 config byte for byte 2`] = `"f2d19e9d678d902f9e7dcb85e0eb28ee95caaf28bd32e063d7dfd7bf21a7d4a6"`;