@segmentstream/app 0.0.0-stage → 0.38.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 (125) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +2 -0
  3. package/README.md +1236 -2
  4. package/dist/agent.d.ts +56 -0
  5. package/dist/agent.js +203 -0
  6. package/dist/app.d.ts +82 -0
  7. package/dist/app.js +434 -0
  8. package/dist/browser-auth-capability.d.ts +2 -0
  9. package/dist/browser-auth-capability.js +2 -0
  10. package/dist/browser-revision.d.ts +19 -0
  11. package/dist/browser-revision.js +140 -0
  12. package/dist/channel-protocol.d.ts +16 -0
  13. package/dist/channel-protocol.js +17 -0
  14. package/dist/channel-session.d.ts +22 -0
  15. package/dist/channel-session.js +89 -0
  16. package/dist/config.d.ts +53 -0
  17. package/dist/config.js +112 -0
  18. package/dist/context.d.ts +10 -0
  19. package/dist/context.js +1 -0
  20. package/dist/cookies.d.ts +56 -0
  21. package/dist/cookies.js +131 -0
  22. package/dist/data.d.ts +233 -0
  23. package/dist/data.js +206 -0
  24. package/dist/decision-pages.d.ts +14 -0
  25. package/dist/decision-pages.js +87 -0
  26. package/dist/deployment.d.ts +30 -0
  27. package/dist/deployment.js +72 -0
  28. package/dist/errors.d.ts +60 -0
  29. package/dist/errors.js +123 -0
  30. package/dist/federation.d.ts +24 -0
  31. package/dist/federation.js +613 -0
  32. package/dist/groups.d.ts +95 -0
  33. package/dist/groups.js +280 -0
  34. package/dist/handlers.d.ts +10 -0
  35. package/dist/handlers.js +161 -0
  36. package/dist/index.d.ts +46 -0
  37. package/dist/index.js +29 -0
  38. package/dist/jobs.d.ts +49 -0
  39. package/dist/jobs.js +40 -0
  40. package/dist/legacy.d.ts +77 -0
  41. package/dist/legacy.js +57 -0
  42. package/dist/logo.d.ts +1 -0
  43. package/dist/logo.js +25 -0
  44. package/dist/me.d.ts +42 -0
  45. package/dist/me.js +54 -0
  46. package/dist/navigation/build.d.ts +68 -0
  47. package/dist/navigation/build.js +290 -0
  48. package/dist/navigation/cli.d.ts +19 -0
  49. package/dist/navigation/cli.js +37 -0
  50. package/dist/navigation/generate.d.ts +43 -0
  51. package/dist/navigation/generate.js +138 -0
  52. package/dist/navigation/next.d.ts +10 -0
  53. package/dist/navigation/next.js +18 -0
  54. package/dist/navigation-protocol.d.ts +55 -0
  55. package/dist/navigation-protocol.js +298 -0
  56. package/dist/neon.d.ts +101 -0
  57. package/dist/neon.js +539 -0
  58. package/dist/oauth-completion.d.ts +6 -0
  59. package/dist/oauth-completion.js +106 -0
  60. package/dist/oauth.d.ts +59 -0
  61. package/dist/oauth.js +129 -0
  62. package/dist/ontology-names.d.ts +10 -0
  63. package/dist/ontology-names.js +38 -0
  64. package/dist/ontology-transport.d.ts +34 -0
  65. package/dist/ontology-transport.js +130 -0
  66. package/dist/ontology-wire.d.ts +66 -0
  67. package/dist/ontology-wire.js +355 -0
  68. package/dist/ontology.d.ts +381 -0
  69. package/dist/ontology.js +367 -0
  70. package/dist/pages.d.ts +6 -0
  71. package/dist/pages.js +6 -0
  72. package/dist/parameters.d.ts +55 -0
  73. package/dist/parameters.js +118 -0
  74. package/dist/permissions.d.ts +19 -0
  75. package/dist/permissions.js +55 -0
  76. package/dist/pkce.d.ts +8 -0
  77. package/dist/pkce.js +40 -0
  78. package/dist/proxy.d.ts +25 -0
  79. package/dist/proxy.js +135 -0
  80. package/dist/request-timing.d.ts +6 -0
  81. package/dist/request-timing.js +53 -0
  82. package/dist/return-to.d.ts +2 -0
  83. package/dist/return-to.js +24 -0
  84. package/dist/server.d.ts +11 -0
  85. package/dist/server.js +80 -0
  86. package/dist/sessions.d.ts +27 -0
  87. package/dist/sessions.js +72 -0
  88. package/dist/sign-in.d.ts +37 -0
  89. package/dist/sign-in.js +95 -0
  90. package/dist/storage.d.ts +79 -0
  91. package/dist/storage.js +180 -0
  92. package/dist/telegram-launch.d.ts +7 -0
  93. package/dist/telegram-launch.js +134 -0
  94. package/dist/telegram.d.ts +2 -0
  95. package/dist/telegram.js +6 -0
  96. package/dist/tokens.d.ts +51 -0
  97. package/dist/tokens.js +70 -0
  98. package/dist/ui/agent-connect.d.ts +18 -0
  99. package/dist/ui/agent-connect.js +23 -0
  100. package/dist/ui/components.d.ts +27 -0
  101. package/dist/ui/components.js +71 -0
  102. package/dist/ui/hooks.d.ts +19 -0
  103. package/dist/ui/hooks.js +56 -0
  104. package/dist/ui/index.d.ts +22 -0
  105. package/dist/ui/index.js +15 -0
  106. package/dist/ui/navigation.d.ts +5 -0
  107. package/dist/ui/navigation.js +8 -0
  108. package/dist/ui/segmentstream-logo.d.ts +2 -0
  109. package/dist/ui/segmentstream-logo.js +7 -0
  110. package/dist/ui/sign-in-check.d.ts +14 -0
  111. package/dist/ui/sign-in-check.js +41 -0
  112. package/dist/ui/sign-in.d.ts +17 -0
  113. package/dist/ui/sign-in.js +65 -0
  114. package/dist/ui/store.d.ts +80 -0
  115. package/dist/ui/store.js +280 -0
  116. package/dist/ui/styles.css +249 -0
  117. package/dist/ui/telegram-sign-in.d.ts +16 -0
  118. package/dist/ui/telegram-sign-in.js +21 -0
  119. package/dist/ui/use-browser-sign-in.d.ts +52 -0
  120. package/dist/ui/use-browser-sign-in.js +169 -0
  121. package/dist/ui/use-channel-sign-in.d.ts +10 -0
  122. package/dist/ui/use-channel-sign-in.js +118 -0
  123. package/dist/ui/use-sign-in.d.ts +109 -0
  124. package/dist/ui/use-sign-in.js +304 -0
  125. package/package.json +95 -4
package/dist/jobs.d.ts ADDED
@@ -0,0 +1,49 @@
1
+ /** A pipeline run, returned immediately by `run()` and refreshed with `getRun()`. */
2
+ export interface JobRun {
3
+ readonly id: string;
4
+ readonly deploymentId: string;
5
+ readonly jobName: string;
6
+ /** `queued`, `starting`, `running`, `succeeded`, `failed` or `cancelled`; future values are accepted. */
7
+ readonly status: string;
8
+ readonly trigger: string;
9
+ readonly partitionRange?: {
10
+ readonly startDate: string;
11
+ readonly endDate: string;
12
+ };
13
+ readonly failure?: {
14
+ readonly code: string;
15
+ readonly detail: string;
16
+ readonly retryable: boolean;
17
+ readonly reference: string;
18
+ };
19
+ readonly createdAt: string;
20
+ readonly updatedAt: string;
21
+ readonly startedAt?: string;
22
+ readonly completedAt?: string;
23
+ }
24
+ export interface JobRunOptions {
25
+ /** Reuse the same key when retrying one submission. Defaults to a new UUID for each call. */
26
+ readonly idempotencyKey?: string;
27
+ readonly partitionRange?: {
28
+ readonly startDate: string;
29
+ readonly endDate: string;
30
+ };
31
+ readonly signal?: AbortSignal;
32
+ }
33
+ export interface JobReadOptions {
34
+ readonly signal?: AbortSignal;
35
+ }
36
+ /**
37
+ * Server-only pipeline execution. The workspace credential can start and read only jobs deployed
38
+ * with `allow_app_runs=True`. Check the app user's permissions before calling on their behalf.
39
+ */
40
+ export interface JobsClient {
41
+ /** Submit a run without waiting for completion. */
42
+ readonly run: (jobName: string, options?: JobRunOptions) => Promise<JobRun>;
43
+ readonly getRun: (runId: string, options?: JobReadOptions) => Promise<JobRun>;
44
+ readonly listRuns: (jobName: string, options?: JobReadOptions) => Promise<readonly JobRun[]>;
45
+ }
46
+ export declare function createJobsClient(dependencies: {
47
+ readonly workspace: string;
48
+ readonly fetch: (path: string, init: RequestInit) => Promise<Response>;
49
+ }): JobsClient;
package/dist/jobs.js ADDED
@@ -0,0 +1,40 @@
1
+ import { apiErrorFrom, readJson } from "./errors.js";
2
+ export function createJobsClient(dependencies) {
3
+ async function request(path, init) {
4
+ const response = await dependencies.fetch(path, init);
5
+ const payload = await readJson(response);
6
+ if (!response.ok) {
7
+ throw apiErrorFrom(response.status, payload, "SegmentStream rejected the job request.");
8
+ }
9
+ return payload;
10
+ }
11
+ return {
12
+ async run(jobName, options = {}) {
13
+ const key = options.idempotencyKey?.trim() ?? crypto.randomUUID();
14
+ if (!/^[A-Za-z0-9._:-]{8,128}$/.test(key)) {
15
+ throw new TypeError("idempotencyKey must be 8–128 letters, numbers, dots, underscores, colons or hyphens.");
16
+ }
17
+ const { run } = await request(`${dependencies.workspace}/jobs/${segment(jobName, "jobName")}/runs`, {
18
+ method: "POST",
19
+ headers: { "content-type": "application/json", "idempotency-key": key },
20
+ body: JSON.stringify(options.partitionRange ? { partitionRange: options.partitionRange } : {}),
21
+ signal: options.signal,
22
+ });
23
+ return run;
24
+ },
25
+ async getRun(runId, options = {}) {
26
+ const { run } = await request(`${dependencies.workspace}/runs/${segment(runId, "runId")}?includeTrigger=true`, { method: "GET", signal: options.signal });
27
+ return run;
28
+ },
29
+ async listRuns(jobName, options = {}) {
30
+ const { runs } = await request(`${dependencies.workspace}/jobs/${segment(jobName, "jobName")}/runs?includeTrigger=true`, { method: "GET", signal: options.signal });
31
+ return runs;
32
+ },
33
+ };
34
+ }
35
+ function segment(value, name) {
36
+ if (!value || value === "." || value === "..") {
37
+ throw new TypeError(`${name} must be a non-empty identifier.`);
38
+ }
39
+ return encodeURIComponent(value);
40
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Metrics were called measures before the ontology SDK's manifest version 14, and metric queries
3
+ * @legacy ontology.metric-earlier-names
4
+ * aggregates. This module is the one place that still knows the earlier names: app code written for
5
+ * an earlier app SDK calls `aggregate` with `measures` and `orderBy[].measure`, an app may type its
6
+ * client with an ontology built by an earlier ontology SDK, whose entities and model declare
7
+ * `measures`, and a workspace may still run an ontology service built by such an SDK, which serves
8
+ * metric queries only at `/api/ontology/aggregate` and `/api/ontology/<entity>/aggregate` with the
9
+ * earlier names. The client writes the current names, and reads the earlier ones through this
10
+ * module.
11
+ */
12
+ import type { EntityMetricQuery, MetricQuery, MetricQueryField, MetricQueryFilter, MetricQueryFilterOperator, MetricQueryGranularity, MetricQueryResult } from "./data.js";
13
+ import type { DeclaredNames, EntityMetricQueryClient, MetricQueryClient, RequestOptions } from "./ontology.js";
14
+ /**
15
+ * A metric query with its metrics under their earlier name, `measures`, and each order's under
16
+ * `measure`.
17
+ */
18
+ type WithEarlierNames<Query extends {
19
+ readonly orderBy?: ReadonlyArray<object>;
20
+ }, Metric extends string> = Omit<Query, "metrics" | "orderBy"> & {
21
+ readonly measures: readonly Metric[];
22
+ readonly orderBy?: ReadonlyArray<Omit<NonNullable<Query["orderBy"]>[number], "metric"> & {
23
+ readonly measure?: Metric;
24
+ }>;
25
+ };
26
+ /** @deprecated Use {@link EntityMetricQuery}: its metrics are `metrics` and `orderBy[].metric`. */
27
+ export type AggregateRequest<Property extends string = string, Measure extends string = string, Temporal extends Property = Property, Path extends string = never> = WithEarlierNames<EntityMetricQuery<Property, Measure, Temporal, Path>, Measure>;
28
+ /** @deprecated Use {@link MetricQuery}: its metrics are `metrics` and `orderBy[].metric`. */
29
+ export type ModelAggregateRequest<Measure extends string = string, Dimension extends string = string> = WithEarlierNames<MetricQuery<Measure, Dimension>, Measure>;
30
+ /** @deprecated Use {@link MetricQueryFilter}. */
31
+ export type ModelAggregateFilter<Dimension extends string = string> = MetricQueryFilter<Dimension>;
32
+ /** @deprecated Use {@link MetricQueryFilterOperator}. */
33
+ export type AggregateFilterOperator = MetricQueryFilterOperator;
34
+ /** @deprecated Use {@link MetricQueryGranularity}. */
35
+ export type AggregateGranularity = MetricQueryGranularity;
36
+ /** @deprecated Use {@link MetricQueryField}. */
37
+ export type AggregateField = MetricQueryField;
38
+ /** @deprecated Use {@link MetricQueryResult}. */
39
+ export type AggregateResult<Row = Record<string, string | boolean | null>> = MetricQueryResult<Row>;
40
+ /** @deprecated Use {@link MetricQueryClient}. */
41
+ export type ModelAggregateClient<Measure extends string = string, Dimension extends string = string> = MetricQueryClient<Measure, Dimension>;
42
+ /** @deprecated Use {@link EntityMetricQueryClient}. */
43
+ export type AggregateEntityClient<Property extends string = string, Measure extends string = string, Temporal extends Property = Property, Path extends string = never> = EntityMetricQueryClient<Property, Measure, Temporal, Path>;
44
+ /** The model-level `queryMetrics` under its earlier name. */
45
+ export interface EarlierQueryMetricsName<Metric extends string, Dimension extends string> {
46
+ /**
47
+ * @deprecated Use `queryMetrics`: `aggregate` is its earlier name. It also takes the metrics as
48
+ * `measures` and an order's metric as `measure`.
49
+ */
50
+ readonly aggregate: (request: MetricQuery<Metric, Dimension> | ModelAggregateRequest<Metric, Dimension>, options?: RequestOptions) => Promise<MetricQueryResult>;
51
+ }
52
+ /** An entity's `queryMetrics` under its earlier name. */
53
+ export interface EarlierEntityQueryMetricsName<Property extends string, Metric extends string, Temporal extends Property, Path extends string> {
54
+ /**
55
+ * @deprecated Use `queryMetrics`: `aggregate` is its earlier name. It also takes the metrics as
56
+ * `measures` and an order's metric as `measure`.
57
+ */
58
+ readonly aggregate: (request: EntityMetricQuery<Property, Metric, Temporal, Path> | AggregateRequest<Property, Metric, Temporal, Path>, options?: RequestOptions) => Promise<MetricQueryResult>;
59
+ }
60
+ /**
61
+ * The metrics an entity of an ontology SDK before manifest version 14 declares under their earlier
62
+ * name: a warehouse-backed entity's `measures`, or those of a stored entity's definition.
63
+ */
64
+ export type EarlierMetricsOf<E> = E extends {
65
+ readonly measures: infer M;
66
+ } ? keyof M & string : E extends {
67
+ readonly definition: {
68
+ readonly measures?: infer M;
69
+ };
70
+ } ? DeclaredNames<NonNullable<M>> : never;
71
+ /** The model metrics of such an ontology, `defineOntology({ measures })`, by their bare names. */
72
+ export type EarlierModelMetricsOf<O> = O extends {
73
+ readonly config: {
74
+ readonly measures?: infer M;
75
+ };
76
+ } ? DeclaredNames<NonNullable<M>> : never;
77
+ export {};
package/dist/legacy.js ADDED
@@ -0,0 +1,57 @@
1
+ /** @internal The earlier name of `queryMetrics`, and of the service's `query_metrics` routes. */
2
+ export const EARLIER_QUERY_METRICS = "aggregate";
3
+ /**
4
+ * @internal A client's `queryMetrics` under its earlier name: the same call, which also takes the
5
+ * earlier names of the request.
6
+ */
7
+ export function withEarlierQueryMetricsName(queryMetrics) {
8
+ return {
9
+ [EARLIER_QUERY_METRICS]: (request, options) => queryMetrics(renamedMetricQuery(request, EARLIER_NAMES, CURRENT_NAMES), options),
10
+ };
11
+ }
12
+ // Ontology services built by an earlier ontology SDK.
13
+ /**
14
+ * @internal Posts metric queries to `<base>/<route>`. An ontology service built by an ontology SDK
15
+ * before manifest version 14 serves them only at `<base>/aggregate`, with `measures` and
16
+ * `orderBy[].measure`, and answers 404 at the current route: the query is posted there once more,
17
+ * with those names. Once that route answers anything but 404, the service is an earlier one, and
18
+ * the poster sends every later query of its client there directly.
19
+ */
20
+ export function metricQueryPoster(route, post) {
21
+ let earlierService = false;
22
+ return async (base, body, signal) => {
23
+ if (!earlierService) {
24
+ const response = await post(`${base}/${route}`, body, signal);
25
+ if (response.status !== 404) {
26
+ return response;
27
+ }
28
+ await response.body?.cancel();
29
+ }
30
+ const response = await post(`${base}/${EARLIER_QUERY_METRICS}`, renamedMetricQuery(body, CURRENT_NAMES, EARLIER_NAMES), signal);
31
+ earlierService ||= response.status !== 404;
32
+ return response;
33
+ };
34
+ }
35
+ const CURRENT_NAMES = { metrics: "metrics", metric: "metric" };
36
+ const EARLIER_NAMES = { metrics: "measures", metric: "measure" };
37
+ /**
38
+ * A metric query with its metrics and each order's metric renamed from `from` to `to`. A field
39
+ * that already carries its `to` name is left as given, for the service to refuse both names.
40
+ */
41
+ function renamedMetricQuery(query, from, to) {
42
+ const renamed = renamedKey(query, from.metrics, to.metrics);
43
+ const { orderBy } = renamed;
44
+ return Array.isArray(orderBy)
45
+ ? {
46
+ ...renamed,
47
+ orderBy: orderBy.map((order) => renamedKey(order, from.metric, to.metric)),
48
+ }
49
+ : renamed;
50
+ }
51
+ /** The object with its key `from` renamed `to`, in its place among the others. */
52
+ function renamedKey(value, from, to) {
53
+ if (!Object.hasOwn(value, from) || Object.hasOwn(value, to)) {
54
+ return value;
55
+ }
56
+ return Object.fromEntries(Object.entries(value).map(([key, field]) => [key === from ? to : key, field]));
57
+ }
package/dist/logo.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare const SEGMENTSTREAM_LOGO_URI: string;
package/dist/logo.js ADDED
@@ -0,0 +1,25 @@
1
+ // Official asset: apps/website/public/segmentstream-logo-black.svg. Keep it in sync.
2
+ const SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="283 330 755 162" fill="none">
3
+ <!-- S icon (black) -->
4
+ <path fill="#18181b" d="M342.57,485.52l46.86-61.07c4.2-5.48,3.17-13.33-2.31-17.54l-1.08-0.83c-6.34-4.86-15.42-3.67-20.29,2.67l-29.25,38.12c-9.07,11.82-6.84,28.75,4.98,37.82L342.57,485.52z"/>
5
+ <path fill="#18181b" d="M393.15,410.11c-0.16-15.51-12.79-28.04-28.34-28.04H349.9c-4.94,0-8.95,4.01-8.95,8.95v19.39h42.52l0.01,0.01c0.09,0,0.19-0.01,0.28-0.01c4.37,0,7.9,3.54,7.9,7.9c0,0.9-0.15,1.77-0.43,2.58c0,0,1.25-3.04,1.63-5.72c0.24-1.69,0.29-3.97,0.3-4.77v0c0-0.03,0-0.06,0-0.09C393.15,410.18,393.15,410.11,393.15,410.11z"/>
6
+ <path fill="#18181b" d="M339.43,335.27l-46.86,61.07c-4.2,5.48-3.17,13.33,2.31,17.54l1.08,0.83c6.34,4.86,15.42,3.67,20.29-2.67l29.25-38.12c9.07-11.82,6.84-28.75-4.98-37.82L339.43,335.27z"/>
7
+ <path fill="#18181b" d="M288.85,410.68c0.16,15.51,12.79,28.04,28.34,28.04h14.91c4.94,0,8.95-4.01,8.95-8.95v-19.39h-42.52l-0.01-0.01c-0.09,0-0.19,0.01-0.28,0.01c-4.37,0-7.9-3.54-7.9-7.9c0-0.9,0.15-1.77,0.43-2.58c0,0-1.25,3.04-1.63,5.72c-0.24,1.69-0.29,3.97-0.3,4.77v0c0,0.03,0,0.06,0,0.09C288.85,410.6,288.85,410.68,288.85,410.68z"/>
8
+ <!-- Wordmark: segmentstream (black) -->
9
+ <g fill="#18181b">
10
+ <path d="M452.61,400.96c-1.03-1.65-2.99-3.72-6.2-3.72c-1.45,0-2.48,0.52-3.1,1.14c-0.52,0.52-0.93,1.34-0.93,2.27c0,1.14,0.52,1.86,1.45,2.48c0.62,0.41,1.24,0.62,3.41,1.76l5.16,2.58c2.27,1.14,4.44,2.27,6.09,4.03c2.38,2.38,3.2,5.06,3.2,8.06c0,3.92-1.45,7.33-3.82,9.91c-3.41,3.72-7.64,4.85-12.19,4.85c-2.79,0-6.3-0.41-9.4-2.79c-2.48-1.86-4.54-4.85-5.58-7.95l8.26-3.92c0.52,1.45,1.45,3.3,2.38,4.13c0.62,0.62,2.07,1.65,4.44,1.65c1.55,0,3.2-0.52,4.13-1.45c0.83-0.83,1.45-2.17,1.45-3.41c0-1.24-0.41-2.27-1.34-3.3c-1.24-1.24-2.68-1.96-4.34-2.68l-3.72-1.76c-1.96-0.93-4.34-2.07-5.99-3.72c-2.27-2.17-3.1-4.54-3.1-7.33c0-3.51,1.34-6.92,3.61-9.29c1.96-2.07,5.27-4.13,10.64-4.13c3.1,0,5.58,0.62,8.05,2.27c1.45,0.93,3.41,2.58,4.96,5.37L452.61,400.96z"/>
11
+ <path d="M509.71,423.06c-1.86,3.3-4.54,6.2-7.33,7.95c-3.51,2.27-8.16,3.3-12.81,3.3c-5.78,0-10.53-1.45-14.66-5.58c-4.13-4.13-6.4-10.12-6.4-16.63c0-6.71,2.37-13.22,6.92-17.86c3.61-3.61,8.36-5.89,14.56-5.89c6.92,0,11.36,2.99,13.94,5.68c5.58,5.78,6.09,13.84,6.09,18.38v1.24h-31.19c0.21,3.1,1.55,6.61,3.72,8.78c2.38,2.38,5.27,2.79,7.74,2.79c2.79,0,4.85-0.62,6.92-2.17c1.76-1.34,3.1-3.1,4.03-4.75L509.71,423.06z M499.7,405.4c-0.41-2.38-1.55-4.44-3.1-5.89c-1.34-1.24-3.51-2.48-6.82-2.48c-3.51,0-5.78,1.45-7.12,2.79c-1.45,1.34-2.58,3.41-3.1,5.58H499.7z"/>
12
+ <path d="M552.37,389.5h10.12v39.96c0,10.22-1.14,17.55-7.13,22.62c-2.79,2.27-7.33,4.65-14.46,4.65c-5.06,0-10.12-1.24-14.25-5.37c-3.2-3.2-5.68-8.26-6.4-13.53h9.81c0.41,2.38,1.65,5.16,3.2,6.81c1.24,1.34,3.72,3,7.85,3c4.23,0,6.71-1.65,7.95-2.89c3.3-3.2,3.3-7.75,3.3-10.95v-5.68c-4.65,5.89-10.33,6.2-13.22,6.2c-5.58,0-10.22-1.55-14.35-5.89c-3.92-4.13-6.51-10.02-6.51-17.25c0-7.95,3-13.42,6.4-16.83c4.34-4.44,9.5-5.99,14.77-5.99c4.34,0,9.19,1.45,12.91,5.89V389.5z M533.05,400.34c-2.58,2.38-4.44,6.4-4.44,11.05c0,4.34,1.65,8.57,4.34,10.95c1.86,1.65,4.65,2.89,7.75,2.89c3.2,0,5.99-0.93,8.47-3.51c2.99-3.2,3.82-6.92,3.82-10.22c0-4.85-1.55-8.47-4.13-10.95c-2.48-2.48-5.27-3.1-8.16-3.1C537.91,397.45,535.33,398.17,533.05,400.34z"/>
13
+ <path d="M575.29,389.5h10.12v4.03c3.41-4.13,7.43-5.16,10.74-5.16c4.54,0,8.78,2.17,11.26,6.4c3.61-5.16,9.09-6.4,12.91-6.4c5.27,0,9.91,2.48,12.39,6.82c0.83,1.45,2.27,4.65,2.27,10.95v26.85h-10.12v-23.96c0-4.85-0.52-6.82-0.93-7.75c-0.62-1.65-2.17-3.82-5.78-3.82c-2.48,0-4.65,1.34-5.99,3.2c-1.76,2.48-1.96,6.2-1.96,9.91v22.41h-10.12v-23.96c0-4.85-0.52-6.82-0.93-7.75c-0.62-1.65-2.17-3.82-5.78-3.82c-2.48,0-4.65,1.34-5.99,3.2c-1.76,2.48-1.96,6.2-1.96,9.91v22.41h-10.12V389.5z"/>
14
+ <path d="M686.72,423.06c-1.86,3.3-4.54,6.2-7.33,7.95c-3.51,2.27-8.16,3.3-12.8,3.3c-5.78,0-10.53-1.45-14.66-5.58c-4.13-4.13-6.4-10.12-6.4-16.63c0-6.71,2.38-13.22,6.92-17.86c3.61-3.61,8.36-5.89,14.56-5.89c6.92,0,11.36,2.99,13.94,5.68c5.58,5.78,6.09,13.84,6.09,18.38v1.24h-31.19c0.21,3.1,1.55,6.61,3.72,8.78c2.38,2.38,5.27,2.79,7.75,2.79c2.79,0,4.85-0.62,6.92-2.17c1.76-1.34,3.1-3.1,4.03-4.75L686.72,423.06z M676.7,405.4c-0.41-2.38-1.55-4.44-3.1-5.89c-1.34-1.24-3.51-2.48-6.82-2.48c-3.51,0-5.78,1.45-7.13,2.79c-1.45,1.34-2.58,3.41-3.1,5.58H676.7z"/>
15
+ <path d="M697.46,389.5h10.12v4.03c4.34-4.85,9.29-5.16,11.77-5.16c8.05,0,11.46,4.03,12.81,5.89c1.65,2.38,2.68,5.37,2.68,12.08v26.64h-10.12v-24.16c0-11.05-4.13-11.36-7.95-11.36c-4.54,0-9.19,0.62-9.19,14.66v20.86h-10.12V389.5z"/>
16
+ <path d="M758.08,398.79v34.18h-10.12v-34.18h-4.23v-9.29h4.23v-15.9h10.12v15.9h7.75v9.29H758.08z"/>
17
+ <path d="M791.64,400.96c-1.03-1.65-2.99-3.72-6.2-3.72c-1.45,0-2.48,0.52-3.1,1.14c-0.52,0.52-0.93,1.34-0.93,2.27c0,1.14,0.52,1.86,1.45,2.48c0.62,0.41,1.24,0.62,3.41,1.76l5.16,2.58c2.27,1.14,4.44,2.27,6.09,4.03c2.38,2.38,3.2,5.06,3.2,8.06c0,3.92-1.45,7.33-3.82,9.91c-3.41,3.72-7.64,4.85-12.19,4.85c-2.79,0-6.3-0.41-9.4-2.79c-2.48-1.86-4.54-4.85-5.58-7.95l8.26-3.92c0.52,1.45,1.45,3.3,2.38,4.13c0.62,0.62,2.07,1.65,4.44,1.65c1.55,0,3.2-0.52,4.13-1.45c0.83-0.83,1.45-2.17,1.45-3.41c0-1.24-0.41-2.27-1.34-3.3c-1.24-1.24-2.69-1.96-4.34-2.68l-3.72-1.76c-1.96-0.93-4.34-2.07-5.99-3.72c-2.27-2.17-3.1-4.54-3.1-7.33c0-3.51,1.34-6.92,3.61-9.29c1.96-2.07,5.27-4.13,10.64-4.13c3.1,0,5.58,0.62,8.05,2.27c1.45,0.93,3.41,2.58,4.96,5.37L791.64,400.96z"/>
18
+ <path d="M820.25,398.79v34.18h-10.12v-34.18h-4.23v-9.29h4.23v-15.9h10.12v15.9h7.75v9.29H820.25z"/>
19
+ <path d="M834.81,389.5h10.12v3.92c1.14-1.34,2.79-2.79,4.23-3.61c1.96-1.14,3.92-1.45,6.2-1.45c2.48,0,5.16,0.41,7.95,2.07l-4.13,9.19c-2.27-1.45-4.13-1.55-5.16-1.55c-2.17,0-4.34,0.31-6.3,2.38c-2.79,2.99-2.79,7.13-2.79,10.02v22.51h-10.12V389.5z"/>
20
+ <path d="M904.83,423.06c-1.86,3.3-4.54,6.2-7.33,7.95c-3.51,2.27-8.16,3.3-12.8,3.3c-5.78,0-10.53-1.45-14.66-5.58c-4.13-4.13-6.4-10.12-6.4-16.63c0-6.71,2.38-13.22,6.92-17.86c3.61-3.61,8.36-5.89,14.56-5.89c6.92,0,11.36,2.99,13.94,5.68c5.58,5.78,6.09,13.84,6.09,18.38v1.24h-31.19c0.21,3.1,1.55,6.61,3.72,8.78c2.38,2.38,5.27,2.79,7.75,2.79c2.79,0,4.85-0.62,6.92-2.17c1.76-1.34,3.1-3.1,4.03-4.75L904.83,423.06z M894.81,405.4c-0.41-2.38-1.55-4.44-3.1-5.89c-1.34-1.24-3.51-2.48-6.82-2.48c-3.51,0-5.78,1.45-7.13,2.79c-1.45,1.34-2.58,3.41-3.1,5.58H894.81z"/>
21
+ <path d="M946.38,389.5h10.12v43.48h-10.12v-4.54c-4.44,5.16-9.91,5.89-13.01,5.89c-13.43,0-21.07-11.15-21.07-23.13c0-14.15,9.71-22.82,21.17-22.82c3.2,0,8.78,0.83,12.91,6.2V389.5z M922.63,411.39c0,7.54,4.75,13.84,12.08,13.84c6.4,0,12.29-4.65,12.29-13.74c0-9.5-5.89-14.04-12.29-14.04C927.38,397.45,922.63,403.64,922.63,411.39z"/>
22
+ <path d="M969.31,389.5h10.12v4.03c3.41-4.13,7.43-5.16,10.74-5.16c4.54,0,8.78,2.17,11.26,6.4c3.62-5.16,9.09-6.4,12.91-6.4c5.27,0,9.91,2.48,12.39,6.82c0.83,1.45,2.27,4.65,2.27,10.95v26.85h-10.12v-23.96c0-4.85-0.52-6.82-0.93-7.75c-0.62-1.65-2.17-3.82-5.78-3.82c-2.48,0-4.65,1.34-5.99,3.2c-1.76,2.48-1.96,6.2-1.96,9.91v22.41H994.1v-23.96c0-4.85-0.52-6.82-0.93-7.75c-0.62-1.65-2.17-3.82-5.78-3.82c-2.48,0-4.65,1.34-5.99,3.2c-1.76,2.48-1.96,6.2-1.96,9.91v22.41h-10.12V389.5z"/>
23
+ </g>
24
+ </svg>`;
25
+ export const SEGMENTSTREAM_LOGO_URI = `data:image/svg+xml,${encodeURIComponent(SVG)}`;
package/dist/me.d.ts ADDED
@@ -0,0 +1,42 @@
1
+ import type { JsonValue } from "./ontology.js";
2
+ export declare const ME_PATH = "/api/ontology/me";
3
+ /**
4
+ * A permission the user holds only for the records its `where` matches, as `/me` sends it. `where`
5
+ * is the condition in the wire form of a query: snake_case field names, and the signed-in user as
6
+ * `{ "$me": [] }` or a path from them as `{ "$me": ["staff_member", "division"] }`. It is
7
+ * informational, for what the app shows; the ontology service enforces it on every read and write.
8
+ */
9
+ export interface ScopedPermission {
10
+ /** `<entity>:<verb>`, spelled as in `permissions`, such as `staffMember:update`. */
11
+ readonly permission: string;
12
+ readonly where: {
13
+ readonly [field: string]: JsonValue;
14
+ };
15
+ }
16
+ /**
17
+ * The signed-in person as the ontology knows them: their `user` record, the roles they hold, the
18
+ * permissions those roles grant, wildcards included, and which of them cover only some records.
19
+ */
20
+ export interface CurrentUser {
21
+ /** The ontology `user` record's id: what relationships such as `lead.ownerId` hold. */
22
+ readonly id: string;
23
+ readonly name: string | null;
24
+ readonly email: string | null;
25
+ /** `member` for people. */
26
+ readonly kind: string;
27
+ readonly active: boolean;
28
+ /** The ontology roles the user holds, such as `sales`. */
29
+ readonly roles: ReadonlyArray<string>;
30
+ /** The permissions the roles grant, such as `lead:changeStatus` or `*:read`. */
31
+ readonly permissions: ReadonlyArray<string>;
32
+ /**
33
+ * The permissions of `permissions` held only for the records their `where` matches. Absent when
34
+ * none is scoped, and from ontologies older than 0.40.0.
35
+ */
36
+ readonly scopes?: ReadonlyArray<ScopedPermission>;
37
+ }
38
+ /**
39
+ * Reads `{ user: { id, name, email, kind, active }, roles, permissions, scopes? }` tolerantly: unknown
40
+ * fields are ignored and only what the SDK presents is checked. `null` when it is not that shape.
41
+ */
42
+ export declare function parseMe(payload: unknown): CurrentUser | null;
package/dist/me.js ADDED
@@ -0,0 +1,54 @@
1
+ /** The ontology service's account of the caller: `GET /api/ontology/me`. */
2
+ import { toCamelCase } from "./ontology-names.js";
3
+ export const ME_PATH = "/api/ontology/me";
4
+ /**
5
+ * Reads `{ user: { id, name, email, kind, active }, roles, permissions, scopes? }` tolerantly: unknown
6
+ * fields are ignored and only what the SDK presents is checked. `null` when it is not that shape.
7
+ */
8
+ export function parseMe(payload) {
9
+ if (typeof payload !== "object" || payload === null) {
10
+ return null;
11
+ }
12
+ const { user, roles, permissions, scopes } = payload;
13
+ if (typeof user !== "object" || user === null) {
14
+ return null;
15
+ }
16
+ const { id, name, email, kind, active } = user;
17
+ if (typeof id !== "string" || id === "") {
18
+ return null;
19
+ }
20
+ const scoped = scopedPermissions(scopes);
21
+ return {
22
+ id,
23
+ name: typeof name === "string" ? name : null,
24
+ email: typeof email === "string" ? email : null,
25
+ kind: typeof kind === "string" ? kind : "member",
26
+ active: typeof active === "boolean" ? active : true,
27
+ roles: strings(roles).map(toCamelCase),
28
+ permissions: strings(permissions).map(toCamelCase),
29
+ ...(scoped.length === 0 ? {} : { scopes: scoped }),
30
+ };
31
+ }
32
+ /** The `{ permission, where }` entries of `scopes`; others are skipped. */
33
+ function scopedPermissions(value) {
34
+ if (!Array.isArray(value)) {
35
+ return [];
36
+ }
37
+ return value.flatMap((entry) => {
38
+ if (typeof entry !== "object" || entry === null) {
39
+ return [];
40
+ }
41
+ const { permission, where } = entry;
42
+ return typeof permission === "string" &&
43
+ typeof where === "object" &&
44
+ where !== null &&
45
+ !Array.isArray(where)
46
+ ? [{ permission: toCamelCase(permission), where: where }]
47
+ : [];
48
+ });
49
+ }
50
+ function strings(value) {
51
+ return Array.isArray(value)
52
+ ? value.filter((item) => typeof item === "string")
53
+ : [];
54
+ }
@@ -0,0 +1,68 @@
1
+ import { generatePageCatalog, type PageCatalogOntology, type PageCatalogRouting } from "./generate.js";
2
+ export * from "./generate.js";
3
+ export { withPageCatalog } from "./next.js";
4
+ export declare const PAGE_CATALOG_PATH = ".segmentstream/navigation/page-catalog.json";
5
+ export declare const PAGE_CATALOG_CONTEXT_PATH = ".segmentstream/navigation/build-context.json";
6
+ export declare const PAGE_CATALOG_COMPILED_PATH = ".segmentstream/navigation/compiled.json";
7
+ /** Read only routing source, never dependencies, generated artifacts, or page modules via import. */
8
+ export declare function readPageCatalogFiles(projectDir: string): Promise<ReadonlyMap<string, string>>;
9
+ interface RoutingRule {
10
+ readonly source: string;
11
+ readonly regex: string;
12
+ readonly internal?: boolean;
13
+ readonly destination?: string;
14
+ readonly has?: readonly unknown[];
15
+ readonly missing?: readonly unknown[];
16
+ }
17
+ interface RoutingInventory {
18
+ readonly redirects: readonly RoutingRule[];
19
+ readonly rewrites: {
20
+ readonly beforeFiles: readonly RoutingRule[];
21
+ readonly afterFiles: readonly RoutingRule[];
22
+ readonly fallback: readonly RoutingRule[];
23
+ };
24
+ }
25
+ /** Prove static matches exactly and compare complete path shapes for dynamic pages. */
26
+ export declare function verifyPageCatalogRouting(catalog: ReturnType<typeof generatePageCatalog>, inventory: RoutingInventory, frameworkInterceptions?: readonly RoutingRule[]): void;
27
+ /** Run before parallel app/ontology builds, using the ontology evaluated from the same immutable source. */
28
+ export declare function preparePageCatalog(input: {
29
+ readonly projectDir: string;
30
+ readonly ontology: PageCatalogOntology;
31
+ readonly sourceHash: string;
32
+ }): Promise<{
33
+ enabled: false;
34
+ coverage: {
35
+ pages: number;
36
+ annotated: number;
37
+ unannotated: number;
38
+ };
39
+ catalog?: undefined;
40
+ catalogPath?: undefined;
41
+ } | {
42
+ enabled: true;
43
+ catalog: import("./generate.js").PageCatalogV1;
44
+ catalogPath: string;
45
+ coverage: {
46
+ pages: number;
47
+ annotated: number;
48
+ unannotated: number;
49
+ };
50
+ }>;
51
+ /** Compiler-stage safety check; final verification below must also follow the complete build command. */
52
+ export declare function verifyCompiledPageCatalog(input: {
53
+ projectDir: string;
54
+ distDir: string;
55
+ routing?: PageCatalogRouting;
56
+ }): Promise<void>;
57
+ /** Verify final resolved routes after any app build command, including custom commands. */
58
+ export declare function verifyPageCatalogBuild(input: {
59
+ readonly projectDir: string;
60
+ }): Promise<{
61
+ enabled: false;
62
+ revision?: undefined;
63
+ pages?: undefined;
64
+ } | {
65
+ enabled: true;
66
+ revision: string;
67
+ pages: number;
68
+ }>;