@opencxh/domain 1.293.0 → 1.295.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 (58) hide show
  1. package/dist/entities/agreement/from-quote.d.ts +18 -0
  2. package/dist/entities/agreement/from-quote.test.d.ts +1 -0
  3. package/dist/entities/agreement/index.d.ts +2 -0
  4. package/dist/entities/agreement/lifecycle.d.ts +44 -0
  5. package/dist/entities/agreement/lifecycle.test.d.ts +1 -0
  6. package/dist/entities/agreement/schedule.d.ts +4 -0
  7. package/dist/entities/agreement/types.d.ts +38 -0
  8. package/dist/entities/bank/match.d.ts +1 -1
  9. package/dist/entities/bookkeeping/receipt.d.ts +95 -2
  10. package/dist/entities/bookkeeping/types.d.ts +2 -0
  11. package/dist/entities/catalog/pricing.d.ts +5 -0
  12. package/dist/entities/catalog/types.d.ts +23 -1
  13. package/dist/entities/company/types.d.ts +6 -0
  14. package/dist/entities/financing/schedule.d.ts +40 -1
  15. package/dist/entities/financing/types.d.ts +99 -3
  16. package/dist/entities/ledger/entry.d.ts +12 -6
  17. package/dist/entities/ledger/template.d.ts +5 -0
  18. package/dist/entities/ledger/types.d.ts +9 -2
  19. package/dist/entities/money/index.d.ts +2 -0
  20. package/dist/entities/money/month-parts.d.ts +19 -0
  21. package/dist/entities/money/month-parts.test.d.ts +1 -0
  22. package/dist/entities/money/period-price.d.ts +23 -0
  23. package/dist/entities/money/period-price.test.d.ts +1 -0
  24. package/dist/entities/money/totals.d.ts +5 -1
  25. package/dist/entities/purchase/contract.d.ts +124 -0
  26. package/dist/entities/purchase/contract.test.d.ts +1 -0
  27. package/dist/entities/purchase/demand.d.ts +68 -0
  28. package/dist/entities/purchase/demand.test.d.ts +1 -0
  29. package/dist/entities/purchase/index.d.ts +7 -0
  30. package/dist/entities/purchase/kinds.d.ts +8 -0
  31. package/dist/entities/purchase/logic.d.ts +35 -0
  32. package/dist/entities/purchase/match.d.ts +98 -0
  33. package/dist/entities/purchase/match.test.d.ts +1 -0
  34. package/dist/entities/purchase/packing-slip.d.ts +82 -0
  35. package/dist/entities/purchase/packing-slip.test.d.ts +1 -0
  36. package/dist/entities/purchase/purchase.test.d.ts +1 -0
  37. package/dist/entities/purchase/types.d.ts +147 -0
  38. package/dist/entities/reports/reports.d.ts +9 -0
  39. package/dist/entities/transaction/document.d.ts +3 -0
  40. package/dist/entities/transaction/keys.d.ts +1 -7
  41. package/dist/entities/transaction/kinds.d.ts +7 -0
  42. package/dist/entities/transaction/types.d.ts +11 -1
  43. package/dist/entities/work/index.d.ts +1 -1
  44. package/dist/entities/work/types.d.ts +1 -1
  45. package/dist/index.cjs +23 -23
  46. package/dist/index.d.ts +3 -1
  47. package/dist/index.js +4187 -3117
  48. package/dist/platform/bookkeeping.d.ts +29 -3
  49. package/dist/platform/manifest.d.ts +6 -27
  50. package/dist/platform/navigation.d.ts +202 -0
  51. package/dist/platform/navigation.test.d.ts +1 -0
  52. package/dist/platform/provider.d.ts +7 -0
  53. package/dist/platform/provisioning.d.ts +88 -0
  54. package/dist/platform/resource.d.ts +19 -0
  55. package/dist/platform/resource.test.d.ts +1 -0
  56. package/dist/platform/routing.d.ts +13 -18
  57. package/package.json +1 -1
  58. package/dist/platform/menu.d.ts +0 -26
@@ -27,8 +27,14 @@ export declare const BOOKKEEPING_ROUTES: {
27
27
  export interface BookingDocument {
28
28
  sourceApp: string;
29
29
  documentId: string;
30
- direction: "sale" | "purchase";
31
- kind: "invoice" | "credit_note" | "receipt";
30
+ /** `none` for a journal: a memorial entry has no buyer or seller side. */
31
+ direction: "sale" | "purchase" | "none";
32
+ /**
33
+ * `journal`: a memorial entry from another app (a payroll journal from HRM or Nmbrs): signed
34
+ * lines on categories, no VAT, `counterparty.name` names it ("Loonjournaal september 2026").
35
+ * Only books that declare the `journal` capability take one; the rest refuse it visibly.
36
+ */
37
+ kind: "invoice" | "credit_note" | "receipt" | "journal";
32
38
  businessEntityId: string;
33
39
  /** Empty for a receipt without a number, and for an invoice the books will number themselves. */
34
40
  number?: string;
@@ -66,9 +72,16 @@ export interface BookingDocument {
66
72
  fileId: string;
67
73
  };
68
74
  externalIds?: string[];
75
+ /**
76
+ * The source's own page for this document, as a shell path (`/apps/sales/<administration>/
77
+ * invoices/<id>`): the books link back to it ("Naar de factuur") without knowing the source.
78
+ */
79
+ path?: string;
69
80
  }
70
81
  export interface BookingLine {
71
82
  description: string;
83
+ /** A journal's line: signed, debit positive. `netCents` and `taxCents` are 0 there. */
84
+ amountCents?: Cents;
72
85
  netCents: Cents;
73
86
  taxCents: Cents;
74
87
  /** `TaxCode.key`. The books map it onto their own box and account. */
@@ -83,8 +96,21 @@ export interface BookingLine {
83
96
  */
84
97
  accountKey?: string;
85
98
  productId?: string;
86
- /** Open map: cost centre, project, and whatever a later country needs. */
99
+ /**
100
+ * Open map: `projectId`, `costCenterId`, `customerCompanyId` (whose cost or revenue this is),
101
+ * and whatever a later country needs. All of it reaches the journal line.
102
+ */
87
103
  dimensions?: Record<string, string>;
104
+ /** The cost of what this line sold (quantity × cost price): carried for margin, not booked yet. */
105
+ costCents?: Cents;
106
+ /**
107
+ * The service period it is for, `YYYY-MM-DD`, `to` inclusive. Own books spread a line over more
108
+ * than one calendar month through the balance (prepaid costs, revenue invoiced ahead).
109
+ */
110
+ period?: {
111
+ from: string;
112
+ to: string;
113
+ };
88
114
  }
89
115
  /** One row of the sweeper's safety net: an issued document the books may not have heard of. */
90
116
  export interface IssuedDocumentRef {
@@ -1,13 +1,12 @@
1
1
  import { IconDefinition } from './common';
2
2
  import { Translations } from './localization';
3
- import { MenuItem } from './menu';
3
+ import { NavContribution, ScopeDefinition } from './navigation';
4
4
  import { RouteDefinition } from './routing';
5
5
  export interface ActionDefinition {
6
6
  displayName: string;
7
7
  description: string;
8
8
  }
9
9
  export interface Modules {
10
- sidebar?: ModuleDefinition;
11
10
  tools?: ModuleDefinition[];
12
11
  assets?: ModuleDefinition[];
13
12
  services?: ModuleDefinition[];
@@ -37,23 +36,6 @@ export type ResourceDefinition<T = any> = T;
37
36
  * It defines the app's identity, its components, its UI contributions,
38
37
  * and most importantly, its security sandbox via the permissions block.
39
38
  */
40
- /** The two groups of the app switcher: the product itself, and what extends it. */
41
- export type AppSwitcherGroup = "core" | "apps";
42
- /**
43
- * Where an app sits in the shell's app switcher. Declaring this — not having an
44
- * `icon` — is what puts an app in the switcher; settings-only and provider apps
45
- * leave it out and stay reachable through settings, panels and docks.
46
- */
47
- export interface AppSwitcherPlacement {
48
- /** `core` is reserved for first-party product apps; everything else is `apps`. */
49
- group: AppSwitcherGroup;
50
- /** Position within `core` — a fixed reading order, not alphabetical. Ignored for `apps`. */
51
- order?: number;
52
- /** Also offer the app in the mobile tab bar. Core apps are there by default. */
53
- mobile?: boolean;
54
- /** Permissions the reader needs before the app is listed at all (`"<app>.<resource>.<action>"`). */
55
- permissions?: string[];
56
- }
57
39
  export interface AppManifest<_TSDK = any> {
58
40
  /**
59
41
  * The namespace of the application.
@@ -79,13 +61,8 @@ export interface AppManifest<_TSDK = any> {
79
61
  * A brief description of what the application does.
80
62
  */
81
63
  description?: string;
82
- /**
83
- * Optional icon for the application. Shown wherever the app is listed; on its own
84
- * it does not place the app in the switcher — see `switcher`.
85
- */
64
+ /** Optional icon for the application, shown wherever the app is listed. */
86
65
  icon?: IconDefinition;
87
- /** Placement in the app switcher and the mobile tab bar. Absent = not listed. */
88
- switcher?: AppSwitcherPlacement;
89
66
  /**
90
67
  * Optional default route for the application.
91
68
  */
@@ -166,8 +143,10 @@ export interface AppManifest<_TSDK = any> {
166
143
  * status page is a URL customers see and link to.
167
144
  */
168
145
  publicBasePath?: string;
169
- /** An array of menu items provided by this application. */
170
- menu?: MenuItem[];
146
+ /** Where this app's entries hang in the workspaces (plan 048). */
147
+ nav?: NavContribution[];
148
+ /** Choices this app owns that decide what pages show, kept on the URL by the shell. */
149
+ scopes?: ScopeDefinition[];
171
150
  /** An array of translations provided by this application. */
172
151
  translations?: Translations;
173
152
  /**
@@ -0,0 +1,202 @@
1
+ /**
2
+ * Navigation by workspace (plan 048). An app owns data and routes; a workspace is a switcher row
3
+ * for a role that shows entries from any app. URL: `/<workspace>/<app>/<path>`.
4
+ */
5
+ /** The default workspaces. An organization can add its own; those carry a free `string` key. */
6
+ export type WorkspaceKey = "home" | "inbox" | "work" | "files" | "customers" | "sales" | "purchase" | "finance" | "knowledge" | "reports";
7
+ /**
8
+ * Workspaces the shell owns rather than `domain` or an organization: `apps` is every app's own
9
+ * workspace (`/apps/<app>/…`), `settings` has the settings categories as its sections.
10
+ */
11
+ export type ReservedWorkspace = "apps" | "settings";
12
+ /** First path segments that are never a workspace key. Every `publicBasePath` joins these. */
13
+ export declare const RESERVED_SEGMENTS: readonly string[];
14
+ /** The administration's scope parameter; organization declares it, `everywhere`. */
15
+ export declare const BUSINESS_ENTITY_PARAM = "businessEntityId";
16
+ export interface ScopeOption {
17
+ id: string;
18
+ /** Display text: options are data (an account name). */
19
+ label: string;
20
+ }
21
+ /**
22
+ * A choice that decides what an app's pages show — the administration, a PBX account, a knowledge
23
+ * base — kept as a query parameter by the shell (plan 048). The shell reads it from the URL, else
24
+ * the last choice, else the first option; writes it onto a page that lacks it; keeps it on every
25
+ * navigation; and hands it to apps as `sdk.router.scope$(param)`. With one option there is no
26
+ * parameter, but the option is still the value.
27
+ */
28
+ export interface ScopeDefinition {
29
+ /**
30
+ * The query parameter, unique across apps, and the prop a page receives it as (`accountId`,
31
+ * `kbId`): the shell hands every page the scopes that hold on it, beside its route params.
32
+ */
33
+ param: string;
34
+ /** i18n key, owner's namespace: what the picker is called. */
35
+ label: string;
36
+ /** In the owner's preferred order: the first is the default. */
37
+ options: () => Subscribable<ScopeOption[]>;
38
+ /**
39
+ * On every URL, and picked in the profile menu (the administration). Otherwise only on the
40
+ * owner's own pages, picked in their header.
41
+ */
42
+ everywhere?: boolean;
43
+ /**
44
+ * The owner's resource to show instead of its pages while there is no option at all ("make your
45
+ * first knowledge base"). Without it the page renders with the prop undefined.
46
+ */
47
+ empty?: string;
48
+ }
49
+ export interface WorkspaceDefinition {
50
+ key: string;
51
+ /**
52
+ * The app the workspace needs: without it the workspace does not exist, and links to it open
53
+ * here by default (its canonical workspace).
54
+ */
55
+ owner: string;
56
+ icon: string;
57
+ order: number;
58
+ /**
59
+ * Section keys, top to bottom. Stable ids (organization config points at them), not i18n
60
+ * keys: the shell shows `section_<key>`, like `workspace_<key>` for the workspace itself.
61
+ */
62
+ sections: string[];
63
+ }
64
+ /** Structural, so domain stays free of rxjs; an Observable fits. */
65
+ export interface Subscribable<T> {
66
+ subscribe(next: (value: T) => void): {
67
+ unsubscribe(): void;
68
+ };
69
+ }
70
+ export interface NavChild {
71
+ id: string;
72
+ /** Display text, not an i18n key: children are data (a project name). */
73
+ label: string;
74
+ /** App-relative. */
75
+ path: string;
76
+ /** Nested levels, e.g. kb sub-collections. */
77
+ children?: NavChild[];
78
+ }
79
+ export interface NavEntry {
80
+ /** Unique within the app; an organization refers to it as `{ app, entry: id }`. */
81
+ id: string;
82
+ /** i18n key, app namespace. */
83
+ label: string;
84
+ /** A Lucide name. Leave it out for rows that hang off their section's rail without a mark. */
85
+ icon?: string;
86
+ /** App-relative, like `RouteDefinition.path`. */
87
+ path: string;
88
+ /**
89
+ * Live children: kb collections, work projects, storage mounts. A function because the app's
90
+ * stores exist only after `initialize`; the shell calls it when the column shows.
91
+ */
92
+ children?: () => Subscribable<NavChild[]>;
93
+ permissions?: string[];
94
+ }
95
+ /**
96
+ * An app hangs entries in one section of a workspace; it lands only where the workspace exists
97
+ * (its owner is there). An app that lands nowhere gets its own, as with `"apps"`.
98
+ */
99
+ export interface NavContribution {
100
+ workspace: WorkspaceKey | "apps";
101
+ /**
102
+ * In a shared workspace a key from its `sections`: an app never invents a heading there. In
103
+ * `"apps"` the app is alone, so its keys are free and labelled `<app>:section_<key>`, in
104
+ * manifest order. Absent = the first section.
105
+ */
106
+ section?: string;
107
+ entries: NavEntry[];
108
+ }
109
+ export interface NavEntryRef {
110
+ app: string;
111
+ entry: string;
112
+ }
113
+ /**
114
+ * What an organization changes on top of the defaults, one document per workspace in
115
+ * apps/organization. A difference, not a copy: whatever it leaves out comes from the default.
116
+ */
117
+ export interface OrgWorkspaceConfig {
118
+ /** A default key (override) or a new one (the organization's own workspace). */
119
+ key: string;
120
+ /** Own workspaces carry text, not an i18n key. */
121
+ label?: string;
122
+ icon?: string;
123
+ order?: number;
124
+ /** Omitted = visible. */
125
+ visibleByDefault?: boolean;
126
+ /** Omitted = everyone. */
127
+ audience?: {
128
+ teamIds: string[];
129
+ };
130
+ /**
131
+ * Omitted = the default layout; a section without `entries` keeps its default entries. On a
132
+ * default workspace every entry not placed here and not `excluded` still lands at the bottom of
133
+ * its own section, so an app installed later shows up. An own workspace is exactly this list.
134
+ */
135
+ sections?: {
136
+ key: string;
137
+ label?: string;
138
+ entries?: NavEntryRef[];
139
+ }[];
140
+ /** Default entries the organization took out of a default workspace. */
141
+ excluded?: NavEntryRef[];
142
+ }
143
+ /** What one user changes: which workspaces they see. Never the contents. */
144
+ export interface UserWorkspacePrefs {
145
+ /** Turned on although hidden by default. */
146
+ shown: string[];
147
+ /** Turned off although visible by default. */
148
+ hidden: string[];
149
+ }
150
+ /** Where to go, never a URL: a page of an app, or a record (`"product:p-1042"`). */
151
+ export type Destination = {
152
+ app: string;
153
+ path: string;
154
+ } | {
155
+ ref: string;
156
+ };
157
+ /** The part of the nav model the resolution rule reads. Built by the shell. */
158
+ export interface WorkspaceIndex {
159
+ /** Visible workspaces for this user, in switcher order. */
160
+ visible: readonly string[];
161
+ /**
162
+ * Per app, the visible workspaces it contributes to, the one it owns first; `"apps"` when it
163
+ * contributes to its own. First = canonical.
164
+ */
165
+ byApp: Readonly<Record<string, readonly string[]>>;
166
+ }
167
+ export interface ResolveInput {
168
+ app: string;
169
+ /**
170
+ * Workspace segment of the URL, if any. Valid when it is visible and either the app contributes
171
+ * to it or the page is a `kind` page (a record opened from there keeps its column on refresh).
172
+ */
173
+ requested?: string;
174
+ /** Workspace on screen now. */
175
+ current?: string;
176
+ /** The route declares `kind`: a page of one thing opens where you are. */
177
+ isRecord: boolean;
178
+ index: WorkspaceIndex;
179
+ }
180
+ /**
181
+ * Which workspace shows this page: the one in the URL, else the one on screen, else the app's
182
+ * canonical one, else its own (`"apps"`). A `kind` page may stay in any visible shared workspace;
183
+ * never in `"apps"`, which is one app's own. A result other than `requested` means: correct the URL.
184
+ */
185
+ export declare function resolveWorkspace({ app, requested, current, isRecord, index, }: ResolveInput): string;
186
+ /** The default layout, in switcher order. Icons are the owner app's own mark. */
187
+ export declare const DEFAULT_WORKSPACES: readonly WorkspaceDefinition[];
188
+ /** A shell URL taken apart: `/<workspace>/<app>/<path>`. */
189
+ export interface WorkspacePath {
190
+ workspace: string;
191
+ /** Absent on a bare workspace URL (`/sales`): the shell opens its first entry. */
192
+ app?: string;
193
+ /** App-relative, with query and hash; `"/"` when there is nothing after the app. */
194
+ path: string;
195
+ }
196
+ /**
197
+ * Reads a shell URL, or null when the first segment is no workspace (a public page, `/wake`).
198
+ * `isWorkspace` comes from the nav model: organization keys are data, so domain cannot list them.
199
+ */
200
+ export declare function parseWorkspacePath(url: string, isWorkspace: (key: string) => boolean): WorkspacePath | null;
201
+ /** The other way round. `path` is app-relative; a missing leading slash is added. */
202
+ export declare function workspacePath({ workspace, app, path }: WorkspacePath): string;
@@ -0,0 +1 @@
1
+ export {};
@@ -169,4 +169,11 @@ export interface DownloadAttachmentPayload {
169
169
  id?: string;
170
170
  /** Conversation id (Teams chatId) — needed to proxy chat hostedContent. */
171
171
  conversationId?: string;
172
+ /**
173
+ * RFC-822 Message-ID plus the attachment's name/size: lets a provider whose
174
+ * `id`/`attachmentId` change on a folder move (Outlook) find the file again.
175
+ */
176
+ rfcMessageId?: string;
177
+ filename?: string;
178
+ size?: number;
172
179
  }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * `provisioning-source`: an app that can order at a supplier through its API (Eylo: a customer
3
+ * account, numbers). Purchase submits a request per order line and follows it; the provider says
4
+ * what it needs and what it made.
5
+ */
6
+ export declare const PROVISIONING_SOURCE_GROUP = "provisioning-source";
7
+ export declare const PROVISIONING_ROUTES: {
8
+ readonly describe: "/provisioning/describe";
9
+ readonly submit: "/provisioning/submit";
10
+ readonly status: "/provisioning/status";
11
+ };
12
+ export type ProvisioningAction = "purchase" | "change" | "suspend" | "resume" | "cancel";
13
+ /**
14
+ * A field the supplier needs. `ordering` is filled on the order line before it goes (the tenant's
15
+ * domain, the number's region); `fulfillment` is what the supplier hands back (the account id).
16
+ */
17
+ export interface ProvisioningParam {
18
+ key: string;
19
+ label: string;
20
+ phase: "ordering" | "fulfillment";
21
+ type?: "text" | "email" | "select";
22
+ required?: boolean;
23
+ options?: {
24
+ value: string;
25
+ label: string;
26
+ }[];
27
+ }
28
+ export interface ProvisionableOffer {
29
+ /** The provider's own key, matched by `SupplierOffer.provider.offer`. */
30
+ key: string;
31
+ label: string;
32
+ /**
33
+ * `account`: the customer's place at the supplier (a tenant, an Eylo account), made once and
34
+ * first. `item`: something inside it (licences, numbers), which `requires` an account.
35
+ */
36
+ level: "account" | "item";
37
+ requires?: string;
38
+ params: ProvisioningParam[];
39
+ actions: ProvisioningAction[];
40
+ /** The account it makes is a usage source: approved links it to the customer's agreement. */
41
+ usageAccount?: boolean;
42
+ }
43
+ export interface ProvisioningDescription {
44
+ offers: ProvisionableOffer[];
45
+ }
46
+ export interface ProvisioningRequest {
47
+ /** `lineKey` of the order line: the provider's idempotency key — the same request twice is one. */
48
+ requestId: string;
49
+ offer: string;
50
+ action: ProvisioningAction;
51
+ quantity: number;
52
+ params: Record<string, string>;
53
+ /** The subscription this changes or ends. */
54
+ externalRef?: string;
55
+ /** What the account level handed back (its id), for an item inside it. */
56
+ parent?: {
57
+ externalRef?: string;
58
+ fulfillment?: Record<string, string>;
59
+ };
60
+ /** Bought elsewhere and landing here: what the purchase handed back (the numbers). */
61
+ predecessor?: {
62
+ externalRef?: string;
63
+ fulfillment?: Record<string, string>;
64
+ };
65
+ customer?: {
66
+ companyId: string;
67
+ name?: string;
68
+ };
69
+ /** When a change or cancellation takes effect (epoch ms); absent = now. */
70
+ effectiveAt?: number;
71
+ }
72
+ export type ProvisioningState = "pending" | "approved" | "failed" | "inquiring";
73
+ export interface ProvisioningResult {
74
+ state: ProvisioningState;
75
+ externalRef?: string;
76
+ fulfillment?: Record<string, string>;
77
+ /** `inquiring`: which ordering fields are missing or wrong. */
78
+ missing?: {
79
+ key: string;
80
+ reason: string;
81
+ }[];
82
+ error?: string;
83
+ /** The account is a usage source: the agreement reads usage from it from now on. */
84
+ usageAccount?: {
85
+ app: string;
86
+ accountRef: string;
87
+ };
88
+ }
@@ -17,6 +17,25 @@ export interface ResourceRef {
17
17
  }
18
18
  /** The key shape `authorizeScope` and the file keys use. */
19
19
  export declare function refKey(ref: ResourceRef): string;
20
+ /** One line inside a resource: invoice line, receipt line, agreement line. */
21
+ export interface LineRef extends ResourceRef {
22
+ lineId: string;
23
+ }
24
+ /**
25
+ * `"invoice:412#l3"` — a line, anywhere. Kind names are unique across apps, so the key alone says
26
+ * whose line it is. Never an array index: a line removed above it would shift every key below.
27
+ */
28
+ export declare function lineKey(ref: LineRef): string;
29
+ export declare function parseLineKey(key: string): LineRef | null;
30
+ /**
31
+ * Gives every line without an id its own (`l<n>`, above the highest in use), keeping the ids that
32
+ * are there: a line keeps its id for life, so what points at it keeps pointing.
33
+ */
34
+ export declare function withLineIds<T extends {
35
+ id?: string;
36
+ }>(lines: readonly T[]): (T & {
37
+ id: string;
38
+ })[];
20
39
  /**
21
40
  * The kind comms owns, and the only one the engine knows something extra about: on an interaction
22
41
  * you can wait for a reply and put a line in the timeline. Other kinds cannot, and that is not an
@@ -0,0 +1 @@
1
+ export {};
@@ -37,6 +37,16 @@ export interface RouteDefinition {
37
37
  * which hands the page to somebody else's brand entirely.
38
38
  */
39
39
  chrome?: "none";
40
+ /**
41
+ * The scope kind this route shows one of (`"order"` on `/order/:id`). Such a page opens in the
42
+ * workspace on screen; a list page only in workspaces the app contributes to.
43
+ */
44
+ kind?: string;
45
+ /**
46
+ * The page works without its app's own scopes (plan 048): the shell neither waits for them nor
47
+ * shows the scope's `empty` page — the one that creates the first knowledge base, say.
48
+ */
49
+ unscoped?: boolean;
40
50
  }
41
51
  export interface NamespacedRouteDefinition extends RouteDefinition {
42
52
  appName: string;
@@ -56,18 +66,6 @@ export declare const AUTH_APP_NAME = "auth";
56
66
  * thrown TypeError takes the subscription down without a word.
57
67
  */
58
68
  export declare function appNameFromPath(path: string | null | undefined): string | null;
59
- /**
60
- * Does this landing path say where the user wanted to go?
61
- *
62
- * Asked at startup by everything that would otherwise send the user somewhere
63
- * of its own choosing. It has to be one shared answer: the shell and the module
64
- * loader both used to decide this, and the loader's "go to the default app"
65
- * simply ran last and overwrote whatever URL you had opened.
66
- *
67
- * `/wake` counts — the service worker lands there with a provider in the query
68
- * and `WakeRoute` routes onward itself.
69
- */
70
- export declare function isDeepLink(path: string | null | undefined): boolean;
71
69
  /**
72
70
  * The shell's settings route. Not an app: it frames the pages every app registers,
73
71
  * so it lives beside `/apps/…` rather than under it.
@@ -82,12 +80,9 @@ export declare function settingsPath(pageId?: string | null): string;
82
80
  * True for the bare root and for the login screen — you are sent there, you do
83
81
  * not go there. Everything else is a request, whether or not it names an app.
84
82
  *
85
- * This is **not** the complement of {@link isDeepLink}. That one answers "does
86
- * this path name an app other than auth", so a public help page — which names
87
- * no app at all — comes back false. Callers that read that false as "the user
88
- * wanted nothing" sent readers of `/help/…` to the organisation's default app.
89
- * Between the two lies the set of paths that might be public, and the only way
90
- * to know is to wait for the app manifests.
83
+ * Its old counterpart `isDeepLink` ("names an app other than auth") read a
84
+ * public help page and every workspace URL as "wanted nothing"; the shell now
85
+ * treats everything that is not a landing path as a destination.
91
86
  */
92
87
  export declare function isLandingPath(path: string | null | undefined): boolean;
93
88
  /** Turn a route pattern with `:param` segments into an exact-match regex. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencxh/domain",
3
- "version": "1.293.0",
3
+ "version": "1.295.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -1,26 +0,0 @@
1
- import { IconDefinition } from './common';
2
- export interface MenuItem {
3
- /** The label of the menu item. */
4
- label: string;
5
- /** The description of the menu item. */
6
- description?: string;
7
- /** The path of the menu item. */
8
- path: string;
9
- /** The icon of the menu item. */
10
- icon?: IconDefinition;
11
- /** The group of the menu item. */
12
- group?: string;
13
- /** The required capabilities of the menu item. */
14
- requiredCapabilities?: string[];
15
- /**
16
- * Permissions (`"<app>.<resource>.<action>"`) the reader needs to see this item. All must hold.
17
- * Absent = visible to everyone. Read `docs/ROLES.md` for the vocabulary.
18
- */
19
- permissions?: string[];
20
- }
21
- export interface NamespacedMenuItem extends MenuItem {
22
- /** The namespace of the menu item. */
23
- namespace: string;
24
- /** The absolute path of the menu item. */
25
- absolutePath: string;
26
- }