@oxyhq/contracts 0.33.0 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -43,9 +43,13 @@ export declare const CHILD_ACCOUNT_KINDS: readonly ["organization", "project", "
43
43
  export type ChildAccountKindGap = Exclude<ChildAccountKind, (typeof CHILD_ACCOUNT_KINDS)[number]>;
44
44
  export declare const childAccountKindSchema: z.ZodEnum<["organization", "project", "bot", "channel"]>;
45
45
  /**
46
- * Whether an operator may ACT AS an account of this kind switch the whole app
47
- * into it (`POST /accounts/:id/switch`) or authorise an app to act as it
48
- * (an OAuth delegated subject).
46
+ * Whether an account of this kind may be the SUBJECT OF A DELEGATION — an
47
+ * application acting as it on some person's authority. `POST /internal/accounts/
48
+ * :id/service-switch` and the OAuth delegated subject both gate on this.
49
+ *
50
+ * It is NOT the question an account switcher asks. See
51
+ * {@link isOperatorSwitchTargetKind}, and the note below on why the difference
52
+ * is `bot`.
49
53
  *
50
54
  * Two kinds are refused, for opposite reasons:
51
55
  *
@@ -62,7 +66,39 @@ export declare const childAccountKindSchema: z.ZodEnum<["organization", "project
62
66
  * Consumers must gate on this predicate rather than testing `kind === 'personal'`,
63
67
  * which silently admits every kind added after it was written.
64
68
  */
65
- export declare function isActAsEligibleKind(kind: AccountKind | null | undefined): boolean;
69
+ export declare function isDelegatedActAsEligibleKind(kind: AccountKind | null | undefined): boolean;
70
+ /**
71
+ * Whether a PERSON may switch into an account of this kind — become it, in an
72
+ * account switcher, for the rest of their session.
73
+ *
74
+ * ## Why this is not the same question as {@link isDelegatedActAsEligibleKind}
75
+ *
76
+ * The two differ on exactly one kind, `bot`, and that difference is the whole
77
+ * reason both exist.
78
+ *
79
+ * **A bot is not something you become. It is something that operates on your
80
+ * behalf.** Its whole purpose is to act while nobody is present: an application
81
+ * holds a credential, names the human whose authority it borrows, and speaks as
82
+ * the bot. That is delegation, and it is what
83
+ * {@link isDelegatedActAsEligibleKind} admits it for.
84
+ *
85
+ * Handing a person the bot's seat instead inverts that. It puts a human inside
86
+ * the identity that exists to act without one, and it does so on the human's own
87
+ * device, next to their personal login — which is precisely what happened: a
88
+ * `bot` account held a live session on a person's device, offered to them by a
89
+ * switcher that had asked the delegation question by mistake.
90
+ *
91
+ * `channel` is refused here as well, for the reason set out above, and
92
+ * `personal` because assuming somebody else's login is impersonation.
93
+ *
94
+ * ## This is the narrower predicate, deliberately
95
+ *
96
+ * Everything a person may become, a service may also act as; the reverse does
97
+ * not hold. A caller that is unsure which question it is asking wants THIS one:
98
+ * being wrong here withholds an affordance, while being wrong the other way
99
+ * hands out a seat.
100
+ */
101
+ export declare function isOperatorSwitchTargetKind(kind: AccountKind | null | undefined): boolean;
66
102
  /**
67
103
  * Narrow an unknown value to an {@link AccountKind}.
68
104
  *
@@ -162,7 +198,7 @@ export declare const accountCategoriesSchema: z.ZodEffects<z.ZodArray<z.ZodEnum<
162
198
  *
163
199
  * A person has interests, not a sector — and their interests are not a
164
200
  * classification anybody else gets to read off their profile. Spelled out
165
- * positively, like {@link isActAsEligibleKind} and for the same reason: a `kind
201
+ * positively, like {@link isDelegatedActAsEligibleKind} and for the same reason: a `kind
166
202
  * !== 'personal'` test silently admits every kind invented after it was
167
203
  * written, whereas this list forces whoever adds one to decide.
168
204
  */
@@ -9,7 +9,7 @@
9
9
  * Platform-agnostic — zod is the only runtime dependency. No react/react-native/
10
10
  * expo, no `require()` in the ESM build.
11
11
  */
12
- export { ACCOUNT_KINDS, accountKindSchema, CHILD_ACCOUNT_KINDS, childAccountKindSchema, isAccountKind, isActAsEligibleKind, ACCOUNT_CATEGORY_IDS, ACCOUNT_CATEGORY_KINDS, accountCategoriesSchema, accountCategoryIdSchema, isSelectableAccountCategoryId, kindAcceptsAccountCategories, MAX_ACCOUNT_CATEGORIES, newlyAddedRetiredCategories, RETIRED_ACCOUNT_CATEGORY_IDS, SELECTABLE_ACCOUNT_CATEGORY_IDS, createAccountRequestSchema, } from './accountGraph';
12
+ export { ACCOUNT_KINDS, accountKindSchema, CHILD_ACCOUNT_KINDS, childAccountKindSchema, isAccountKind, isDelegatedActAsEligibleKind, isOperatorSwitchTargetKind, ACCOUNT_CATEGORY_IDS, ACCOUNT_CATEGORY_KINDS, accountCategoriesSchema, accountCategoryIdSchema, isSelectableAccountCategoryId, kindAcceptsAccountCategories, MAX_ACCOUNT_CATEGORIES, newlyAddedRetiredCategories, RETIRED_ACCOUNT_CATEGORY_IDS, SELECTABLE_ACCOUNT_CATEGORY_IDS, createAccountRequestSchema, } from './accountGraph';
13
13
  export type { AccountKind, AccountCategoryId, AccountCategoryKind, ChildAccountKind, CreateAccountRequest, } from './accountGraph';
14
14
  export { usernameSchema, isValidUsername, stripDisallowedUsernameCharacters, USERNAME_MIN_LENGTH, USERNAME_MAX_LENGTH, USERNAME_INVALID_MESSAGE, } from './username';
15
15
  export { userNameSchema, userRelationshipSchema, themePreferenceSchema, userResponseSchema, userProfileUpdateSchema, currentUserResponseSchema, deviceLinkedSessionSchema, deviceLinkedSessionsResponseSchema, resolveUserId, safeParseContract, } from './userResponse';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxyhq/contracts",
3
- "version": "0.33.0",
3
+ "version": "0.34.0",
4
4
  "description": "OxyHQ API contracts — single source of truth for request/response Zod schemas and inferred types, shared by the backend and the client SDKs",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",