@oxyhq/contracts 0.32.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.
@@ -9,12 +9,14 @@
9
9
  */
10
10
  Object.defineProperty(exports, "__esModule", { value: true });
11
11
  exports.createAccountRequestSchema = exports.ACCOUNT_CATEGORY_KINDS = exports.accountCategoriesSchema = exports.MAX_ACCOUNT_CATEGORIES = exports.SELECTABLE_ACCOUNT_CATEGORY_IDS = exports.RETIRED_ACCOUNT_CATEGORY_IDS = exports.accountCategoryIdSchema = exports.ACCOUNT_CATEGORY_IDS = exports.childAccountKindSchema = exports.CHILD_ACCOUNT_KINDS = exports.accountKindSchema = exports.ACCOUNT_KINDS = void 0;
12
- exports.isActAsEligibleKind = isActAsEligibleKind;
12
+ exports.isDelegatedActAsEligibleKind = isDelegatedActAsEligibleKind;
13
+ exports.isOperatorSwitchTargetKind = isOperatorSwitchTargetKind;
13
14
  exports.isAccountKind = isAccountKind;
14
15
  exports.isSelectableAccountCategoryId = isSelectableAccountCategoryId;
15
16
  exports.newlyAddedRetiredCategories = newlyAddedRetiredCategories;
16
17
  exports.kindAcceptsAccountCategories = kindAcceptsAccountCategories;
17
18
  const zod_1 = require("zod");
19
+ const username_1 = require("./username");
18
20
  /**
19
21
  * The union is spelled out above and the array proves coverage BOTH ways
20
22
  * (`satisfies` here, the `Gap` alias below) — the same shape this package's
@@ -43,9 +45,13 @@ exports.CHILD_ACCOUNT_KINDS = [
43
45
  ];
44
46
  exports.childAccountKindSchema = zod_1.z.enum(exports.CHILD_ACCOUNT_KINDS);
45
47
  /**
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).
48
+ * Whether an account of this kind may be the SUBJECT OF A DELEGATION — an
49
+ * application acting as it on some person's authority. `POST /internal/accounts/
50
+ * :id/service-switch` and the OAuth delegated subject both gate on this.
51
+ *
52
+ * It is NOT the question an account switcher asks. See
53
+ * {@link isOperatorSwitchTargetKind}, and the note below on why the difference
54
+ * is `bot`.
49
55
  *
50
56
  * Two kinds are refused, for opposite reasons:
51
57
  *
@@ -62,9 +68,43 @@ exports.childAccountKindSchema = zod_1.z.enum(exports.CHILD_ACCOUNT_KINDS);
62
68
  * Consumers must gate on this predicate rather than testing `kind === 'personal'`,
63
69
  * which silently admits every kind added after it was written.
64
70
  */
65
- function isActAsEligibleKind(kind) {
71
+ function isDelegatedActAsEligibleKind(kind) {
66
72
  return kind === 'organization' || kind === 'project' || kind === 'bot';
67
73
  }
74
+ /**
75
+ * Whether a PERSON may switch into an account of this kind — become it, in an
76
+ * account switcher, for the rest of their session.
77
+ *
78
+ * ## Why this is not the same question as {@link isDelegatedActAsEligibleKind}
79
+ *
80
+ * The two differ on exactly one kind, `bot`, and that difference is the whole
81
+ * reason both exist.
82
+ *
83
+ * **A bot is not something you become. It is something that operates on your
84
+ * behalf.** Its whole purpose is to act while nobody is present: an application
85
+ * holds a credential, names the human whose authority it borrows, and speaks as
86
+ * the bot. That is delegation, and it is what
87
+ * {@link isDelegatedActAsEligibleKind} admits it for.
88
+ *
89
+ * Handing a person the bot's seat instead inverts that. It puts a human inside
90
+ * the identity that exists to act without one, and it does so on the human's own
91
+ * device, next to their personal login — which is precisely what happened: a
92
+ * `bot` account held a live session on a person's device, offered to them by a
93
+ * switcher that had asked the delegation question by mistake.
94
+ *
95
+ * `channel` is refused here as well, for the reason set out above, and
96
+ * `personal` because assuming somebody else's login is impersonation.
97
+ *
98
+ * ## This is the narrower predicate, deliberately
99
+ *
100
+ * Everything a person may become, a service may also act as; the reverse does
101
+ * not hold. A caller that is unsure which question it is asking wants THIS one:
102
+ * being wrong here withholds an affordance, while being wrong the other way
103
+ * hands out a seat.
104
+ */
105
+ function isOperatorSwitchTargetKind(kind) {
106
+ return kind === 'organization' || kind === 'project';
107
+ }
68
108
  /**
69
109
  * Narrow an unknown value to an {@link AccountKind}.
70
110
  *
@@ -295,7 +335,7 @@ exports.accountCategoriesSchema = zod_1.z
295
335
  *
296
336
  * A person has interests, not a sector — and their interests are not a
297
337
  * classification anybody else gets to read off their profile. Spelled out
298
- * positively, like {@link isActAsEligibleKind} and for the same reason: a `kind
338
+ * positively, like {@link isDelegatedActAsEligibleKind} and for the same reason: a `kind
299
339
  * !== 'personal'` test silently admits every kind invented after it was
300
340
  * written, whereas this list forces whoever adds one to decide.
301
341
  */
@@ -350,7 +390,14 @@ const accountNameSchema = zod_1.z
350
390
  exports.createAccountRequestSchema = zod_1.z.object({
351
391
  parentAccountId: zod_1.z.string().trim().min(1).optional(),
352
392
  kind: exports.childAccountKindSchema,
353
- username: zod_1.z.string().trim().min(1).max(100),
393
+ /**
394
+ * The SAME policy a person's handle is held to. `users.username` is one unique
395
+ * index, so a managed account may not reserve a name a person could not ask
396
+ * for — and this route's predecessor (`.min(1).max(100)` here, `^[\w.-]+$`
397
+ * with no ceiling in the service) is how a one-character or dotted or
398
+ * 100-character handle became reachable for bots alone.
399
+ */
400
+ username: username_1.usernameSchema,
354
401
  name: accountNameSchema,
355
402
  bio: zod_1.z.string().trim().max(500).optional(),
356
403
  avatar: zod_1.z.string().optional(),
package/dist/cjs/index.js CHANGED
@@ -11,22 +11,23 @@
11
11
  * expo, no `require()` in the ESM build.
12
12
  */
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.appInterestInputSchema = exports.appEndorsementInputSchema = exports.recommendationResponseSchema = exports.recommendationItemSchema = exports.recommendationCountSchema = exports.recommendationRequestSchema = exports.recommendationSignalWeightsSchema = exports.recommendationBoostSchema = exports.recommendationExcludeTypeSchema = exports.oxyUserInvalidationEventSchema = exports.isPublishedOxyUserChangeReason = exports.OXY_PUBLISHED_USER_CHANGE_REASONS = exports.OXY_USER_CHANGE_REASONS = exports.OXY_USER_INVALIDATION_CHANNEL = exports.inboxEmailPushDataSchema = exports.INBOX_EMAIL_PUSH_TYPE = exports.INBOX_EMAIL_PUSH_CHANNEL = exports.IDENTITY_APPROVAL_PUSH_CHANNEL = exports.commonsDenyReasonSchema = exports.COMMONS_DENY_REASONS = exports.sessionStatusSchema = exports.publicApplicationSchema = exports.applicationTypeSchema = exports.safeParseContract = exports.resolveUserId = exports.deviceLinkedSessionsResponseSchema = exports.deviceLinkedSessionSchema = exports.currentUserResponseSchema = exports.userProfileUpdateSchema = exports.userResponseSchema = exports.themePreferenceSchema = exports.userRelationshipSchema = exports.userNameSchema = exports.createAccountRequestSchema = exports.SELECTABLE_ACCOUNT_CATEGORY_IDS = exports.RETIRED_ACCOUNT_CATEGORY_IDS = exports.newlyAddedRetiredCategories = exports.MAX_ACCOUNT_CATEGORIES = exports.kindAcceptsAccountCategories = exports.isSelectableAccountCategoryId = exports.accountCategoryIdSchema = exports.accountCategoriesSchema = exports.ACCOUNT_CATEGORY_KINDS = exports.ACCOUNT_CATEGORY_IDS = exports.isActAsEligibleKind = exports.isAccountKind = exports.childAccountKindSchema = exports.CHILD_ACCOUNT_KINDS = exports.accountKindSchema = exports.ACCOUNT_KINDS = void 0;
15
- exports.reputationTargetEntityTypeSchema = exports.trustTierSchema = exports.reputationTransactionStatusSchema = exports.reputationCategorySchema = exports.REPUTATION_INFLUENCE_CONTEXTS = exports.REPUTATION_DISPUTE_STATUSES = exports.REPUTATION_TARGET_ENTITY_TYPES = exports.TRUST_TIERS = exports.REPUTATION_TRANSACTION_STATUSES = exports.REPUTATION_CATEGORIES = exports.credentialVerifyResultSchema = exports.credentialListResultSchema = exports.credentialIssueResultSchema = exports.verifiableCredentialResponseSchema = exports.credentialRecordSchema = exports.vouchResultSchema = exports.personhoodStatusResultSchema = exports.personhoodBreakdownSchema = exports.personhoodVouchRecordSchema = exports.validationVoteResultSchema = exports.validationRequestSummarySchema = exports.validationOpenResultSchema = exports.validationOpenRequestSchema = exports.validationVerdictRecordSchema = exports.realLifeAttestationResultSchema = exports.realLifeAttestationRecordSchema = exports.signedPublicCardSchema = exports.publicCardSchema = exports.logPageResponseSchema = exports.chainHeadResponseSchema = exports.oxySignedRecordTypeSchema = exports.exportBundleSchema = exports.exportFinancialSectionSchema = exports.exportUsageReservationSchema = exports.exportLedgerEntrySchema = exports.exportUsageReceiptSchema = exports.exportAttestationSchema = exports.authMethodsResponseSchema = exports.authMethodEntrySchema = exports.domainVerificationInstructionsSchema = exports.domainVerificationRequestSchema = exports.verifiedDomainSchema = exports.signedRecordEnvelopeSchema = exports.didDocumentSchema = exports.didServiceSchema = exports.verificationMethodSchema = exports.appAffinityEventsIngestSchema = exports.appAffinityEventSchema = exports.appAffinityEventTypeSchema = exports.appUserSignalIngestSchema = void 0;
16
- exports.moderationDecisionEventSubjectSchema = exports.moderationFindingSchema = exports.applicationModerationStandingSchema = exports.identityBindingStatusSchema = exports.identityBindingTypeSchema = exports.personhoodStatusSchema = exports.contributionTierSchema = exports.conductStandingSchema = exports.conductStrikeStatusSchema = exports.moderationEffectSkipReasonSchema = exports.moderationEffectStatusSchema = exports.moderationEffectTypeSchema = exports.moderationDecisionStatusSchema = exports.moderationAttributionSchema = exports.moderationFindingScopeSchema = exports.moderationSeveritySchema = exports.APPLICATION_MODERATION_STANDINGS = exports.IDENTITY_BINDING_STATUSES = exports.IDENTITY_BINDING_TYPES = exports.PERSONHOOD_STATUSES = exports.CONTRIBUTION_TIERS = exports.CONDUCT_STANDINGS = exports.CONDUCT_STRIKE_STATUSES = exports.MODERATION_EFFECT_SKIP_REASONS = exports.MODERATION_EFFECT_STATUSES = exports.MODERATION_EFFECT_TYPES = exports.MODERATION_DECISION_STATUSES = exports.MODERATION_ATTRIBUTIONS = exports.MODERATION_FINDING_SCOPES = exports.MODERATION_SEVERITIES = exports.isFullReputationBalance = exports.reverseReputationTransactionSchema = exports.upsertReputationRuleSchema = exports.resolveReputationDisputeSchema = exports.createReputationDisputeSchema = exports.awardReputationSchema = exports.reverseReputationTransactionResultSchema = exports.reputationInfluenceResultSchema = exports.reputationLeaderboardEntrySchema = exports.reputationLeaderboardUserSchema = exports.reputationRuleSchema = exports.reputationDisputeSchema = exports.reputationBalanceSchema = exports.reputationBalanceSummarySchema = exports.reputationReliabilitySchema = exports.reputationInfluenceSchema = exports.reputationBalanceBreakdownSchema = exports.reputationTransactionSchema = exports.reputationInfluenceContextSchema = exports.reputationDisputeStatusSchema = void 0;
17
- exports.browserHubErrorSchema = exports.browserHubResolveResponseSchema = exports.browserHubHandleResponseSchema = exports.browserHubHandleRequestSchema = exports.browserHubHandleSchema = exports.BROWSER_HUB_HANDLE_TTL_MS = exports.BROWSER_HUB_COOKIE_ATTRIBUTES = exports.BROWSER_HUB_COOKIE_NAME = exports.oauthAuthorizeCodeResponseSchema = exports.oauthConsentDecisionSchema = exports.deviceDirectorySyncSchema = exports.deviceActivateResponseSchema = exports.deviceActivateRequestSchema = exports.deviceDirectorySchema = exports.devicePrincipalSchema = exports.deviceAccountContextSchema = exports.deviceDirectoryProfileSchema = exports.deviceContextRelationshipSchema = exports.sessionAccountsChangedEventSchema = exports.sessionAccountsChangedReasonSchema = exports.SESSION_ACCOUNTS_CHANGED_EVENT = exports.deviceBackgroundTokenResponseSchema = exports.deviceBackgroundTokenRequestSchema = exports.deviceBackgroundCredentialResponseSchema = exports.deviceTokenMintResponseSchema = exports.deviceTokenMintRequestSchema = exports.deviceSessionSyncSchema = exports.activeTokenSchema = exports.deviceSessionStateSchema = exports.sessionAccountSchema = exports.linkPreviewResponseSchema = exports.linkPreviewBatchResponseSchema = exports.linkPreviewBatchRequestSchema = exports.linkPreviewSchema = exports.applicationModerationTrustSchema = exports.reputationContextualInfluenceSchema = exports.reputationReviewingSchema = exports.reputationReportingSchema = exports.reputationConductSchema = exports.reputationContributionSchema = exports.reputationPersonhoodSchema = exports.identityBindingSchema = exports.registerIdentityBindingSchema = exports.reverseModerationEffectResultSchema = exports.applyModerationDecisionResultSchema = exports.moderationEffectSchema = exports.reverseModerationEffectSchema = exports.finalizeModerationDecisionSchema = exports.moderationDecisionEventSchema = exports.moderationPolicyVersionsSchema = void 0;
18
- exports.deviceTransferApproveResponseSchema = exports.deviceTransferApproveRequestSchema = exports.deviceTransferInfoResponseSchema = exports.deviceTransferInitResponseSchema = exports.deviceTransferInitRequestSchema = exports.devicePairingStatusSchema = exports.webauthnLoginVerifyRequestSchema = exports.webauthnRegisterVerifyRequestSchema = exports.webauthnLoginOptionsRequestSchema = exports.webauthnRegisterOptionsRequestSchema = exports.updateRolloutPatchSchema = exports.promoteRequestSchema = exports.rollbackToEmbeddedRequestSchema = exports.rollbackRequestSchema = exports.updateListResponseSchema = exports.channelListResponseSchema = exports.channelSchema = exports.rollbackToEmbeddedEntrySchema = exports.createUpdateResponseSchema = exports.updateSchema = exports.createUpdateRequestSchema = exports.updateAssetRefSchema = exports.assetCompleteResponseSchema = exports.assetCompleteResultItemSchema = exports.assetCompleteRequestSchema = exports.assetInitResponseSchema = exports.assetUploadTicketSchema = exports.assetInitRequestSchema = exports.assetInitItemSchema = exports.rolloutPercentSchema = exports.runtimeVersionSchema = exports.channelNameSchema = exports.sha256HexSchema = exports.updateAssetStatusSchema = exports.updateStatusSchema = exports.updatePlatformSchema = exports.backupStatusResponseSchema = exports.backupUploadRequestSchema = exports.encryptedBackupEnvelopeSchema = exports.backupLookupIdSchema = exports.rotateKeyCompleteResponseSchema = exports.rotateKeyCompleteRequestSchema = exports.rotateKeyChallengeResponseSchema = exports.loginResultSchema = exports.hubAuthorizeResultSchema = exports.hubAuthorizeRequestSchema = exports.hubActivateRequestSchema = exports.hubClaimRequestSchema = exports.hubSessionSchema = exports.browserHubRevokeResponseSchema = void 0;
19
- exports.providerErrorPassthroughSchema = exports.safeErrorTextSchema = exports.upstreamErrorCategorySchema = exports.inferenceErrorCodeSchema = exports.NON_RETRYABLE_INFERENCE_ERROR_CODES = exports.INFERENCE_ERROR_CODES = exports.inferenceAttributionSchema = exports.authenticatedPrincipalSchema = exports.billingPrincipalSchema = exports.inferenceScopeSchema = exports.INFERENCE_SCOPES = exports.unitPriceSchema = exports.usageQuantitySchema = exports.usageSourceSchema = exports.USAGE_SOURCES = exports.usageUnitSchema = exports.USAGE_UNITS = exports.moneySchema = exports.exactDecimalSchema = exports.INFERENCE_MONEY_SCALE = exports.currencyCodeSchema = exports.RESERVED_ALIA_PUBLISHER = exports.inferenceRegionSchema = exports.deploymentIdSchema = exports.inferenceProviderSlugSchema = exports.routingProfileSlugSchema = exports.modelReferenceSchema = exports.modelRevisionLabelSchema = exports.modelIdSchema = exports.modelSlugSchema = exports.publisherSlugSchema = exports.sha256DigestSchema = exports.inferenceHttpsUrlSchema = exports.inferenceDateSchema = exports.inferenceTimestampSchema = exports.inferenceEnvironmentSchema = exports.idempotencyKeySchema = exports.generationIdSchema = exports.requestIdSchema = exports.oxyCredentialIdSchema = exports.oxyApplicationIdSchema = exports.delegatedUserIdSchema = exports.oxyAccountIdSchema = exports.INFERENCE_CONTRACT_VERSION = exports.transparencyCheckpointListSchema = exports.transparencyInclusionProofSchema = exports.transparencyCheckpointSchema = exports.transparencyAnchorSchema = exports.transparencyCheckpointSignatureSchema = exports.deviceTransferDenyResponseSchema = void 0;
20
- exports.samplingParametersSchema = exports.inferenceInputSchema = exports.inferenceMessageSchema = exports.inferenceMessageRoleSchema = exports.inferenceToolCallSchema = exports.inferenceContentPartSchema = exports.inferenceContentSourceSchema = exports.modelDocumentationSchema = exports.modelReleaseIngestionResultSchema = exports.modelReleaseIngestionRequestSchema = exports.modelLineDeclarationSchema = exports.modelGpaiDocumentationSchema = exports.modelDownstreamDocumentationSchema = exports.SYSTEMIC_RISK_COMPUTE_THRESHOLD_FLOPS = exports.trainingComputeFlopsSchema = exports.modelSystemicRiskTierSchema = exports.modelDistributionMethodSchema = exports.aliaModelReleaseManifestSchema = exports.aliaReleaseSignatureSchema = exports.aliaReleaseArtifactSchema = exports.authorizedRouteSchema = exports.routingPolicyReferenceSchema = exports.routingPolicySchema = exports.routingFallbackPolicySchema = exports.routingPolicyScopeSchema = exports.routingTargetSchema = exports.modelCatalogueEntrySchema = exports.catalogueServingProviderSummarySchema = exports.cataloguePublisherSummarySchema = exports.routingProfileSchema = exports.routingProfileCandidateSchema = exports.modelDeploymentSchema = exports.inferenceProviderSchema = exports.modelRevisionSchema = exports.catalogueModelSchema = exports.modelPublisherSchema = exports.modelSafetyMetadataSchema = exports.modelEvaluationResultSchema = exports.modelDeprecationSchema = exports.commercialPermissionSchema = exports.availabilityScopeSchema = exports.inferenceDataPolicySchema = exports.modelProvenanceSchema = exports.modelLicenseSchema = exports.modelCapabilitiesSchema = exports.inferenceModalitySchema = exports.priceSnapshotSchema = exports.priceVersionSchema = exports.priceVersionStatusSchema = exports.inferenceErrorSchema = void 0;
21
- exports.RECONCILIATION_DISCREPANCY_KINDS = exports.autoRechargeAttemptSchema = exports.autoRechargeStatusSchema = exports.AUTO_RECHARGE_STATUSES = exports.externalPaymentSchema = exports.externalPaymentKindSchema = exports.EXTERNAL_PAYMENT_KINDS = exports.externalPaymentProviderSchema = exports.EXTERNAL_PAYMENT_PROVIDERS = exports.billingInvoiceSchema = exports.billingInvoiceStatusSchema = exports.BILLING_INVOICE_STATUSES = exports.accountBillingStateSchema = exports.billingProfileSchema = exports.autoRechargeSchema = exports.billingProfileStatusSchema = exports.BILLING_PROFILE_STATUSES = exports.billingModeSchema = exports.BILLING_MODES = exports.providerConnectionSchema = exports.providerConnectionStatusSchema = exports.providerConnectionValidationSchema = exports.providerSecretReferenceSchema = exports.providerConnectionScopeSchema = exports.PROVIDER_SECRET_REFERENCE_NAMESPACE = exports.usageRefundSchema = exports.usageRefundReasonSchema = exports.usageRefundSubjectSchema = exports.usageReceiptSchema = exports.normalizedUsageReportSchema = exports.inferenceRequestOutcomeSchema = exports.usageReservationSchema = exports.usageReservationStatusSchema = exports.usageReservationRequestSchema = exports.inferenceStreamEventSchema = exports.inferenceStreamDoneEventSchema = exports.inferenceFinishReasonSchema = exports.inferenceStreamErrorEventSchema = exports.inferenceStreamRouteSwitchEventSchema = exports.inferenceRouteSwitchReasonSchema = exports.inferenceRouteSwitchDetailSchema = exports.inferenceStreamUsageEventSchema = exports.inferenceStreamToolCallEventSchema = exports.inferenceStreamDeltaEventSchema = exports.inferenceStreamStartEventSchema = exports.inferenceRequestSchema = exports.clientRequestMetadataSchema = exports.responseFormatSchema = exports.toolChoiceSchema = exports.toolDefinitionSchema = void 0;
22
- exports.productEntitlementSchema = exports.costCenterSpendSchema = exports.costCenterSchema = exports.costCenterStatusSchema = exports.COST_CENTER_STATUSES = exports.payAsYouGoEntitlementSchema = exports.productPlanSchema = exports.planAllowanceSchema = exports.LIVE_PRODUCT_PLAN_STATUSES = exports.productPlanStatusSchema = exports.PRODUCT_PLAN_STATUSES = exports.reconciliationReportSchema = exports.reconciliationRunSchema = exports.reconciliationDiscrepancySchema = exports.reconciliationRunStatusSchema = exports.RECONCILIATION_RUN_STATUSES = exports.reconciliationDiscrepancyKindSchema = void 0;
14
+ exports.recommendationBoostSchema = exports.recommendationExcludeTypeSchema = exports.oxyUserInvalidationEventSchema = exports.isPublishedOxyUserChangeReason = exports.OXY_PUBLISHED_USER_CHANGE_REASONS = exports.OXY_USER_CHANGE_REASONS = exports.OXY_USER_INVALIDATION_CHANNEL = exports.inboxEmailPushDataSchema = exports.INBOX_EMAIL_PUSH_TYPE = exports.INBOX_EMAIL_PUSH_CHANNEL = exports.IDENTITY_APPROVAL_PUSH_CHANNEL = exports.commonsDenyReasonSchema = exports.COMMONS_DENY_REASONS = exports.sessionStatusSchema = exports.publicApplicationSchema = exports.applicationTypeSchema = exports.safeParseContract = exports.resolveUserId = exports.deviceLinkedSessionsResponseSchema = exports.deviceLinkedSessionSchema = exports.currentUserResponseSchema = exports.userProfileUpdateSchema = exports.userResponseSchema = exports.themePreferenceSchema = exports.userRelationshipSchema = exports.userNameSchema = exports.USERNAME_INVALID_MESSAGE = exports.USERNAME_MAX_LENGTH = exports.USERNAME_MIN_LENGTH = exports.stripDisallowedUsernameCharacters = exports.isValidUsername = exports.usernameSchema = exports.createAccountRequestSchema = exports.SELECTABLE_ACCOUNT_CATEGORY_IDS = exports.RETIRED_ACCOUNT_CATEGORY_IDS = exports.newlyAddedRetiredCategories = exports.MAX_ACCOUNT_CATEGORIES = exports.kindAcceptsAccountCategories = exports.isSelectableAccountCategoryId = exports.accountCategoryIdSchema = exports.accountCategoriesSchema = exports.ACCOUNT_CATEGORY_KINDS = exports.ACCOUNT_CATEGORY_IDS = exports.isOperatorSwitchTargetKind = exports.isDelegatedActAsEligibleKind = exports.isAccountKind = exports.childAccountKindSchema = exports.CHILD_ACCOUNT_KINDS = exports.accountKindSchema = exports.ACCOUNT_KINDS = void 0;
15
+ exports.TRUST_TIERS = exports.REPUTATION_TRANSACTION_STATUSES = exports.REPUTATION_CATEGORIES = exports.credentialVerifyResultSchema = exports.credentialListResultSchema = exports.credentialIssueResultSchema = exports.verifiableCredentialResponseSchema = exports.credentialRecordSchema = exports.vouchResultSchema = exports.personhoodStatusResultSchema = exports.personhoodBreakdownSchema = exports.personhoodVouchRecordSchema = exports.validationVoteResultSchema = exports.validationRequestSummarySchema = exports.validationOpenResultSchema = exports.validationOpenRequestSchema = exports.validationVerdictRecordSchema = exports.realLifeAttestationResultSchema = exports.realLifeAttestationRecordSchema = exports.signedPublicCardSchema = exports.publicCardSchema = exports.logPageResponseSchema = exports.chainHeadResponseSchema = exports.oxySignedRecordTypeSchema = exports.exportBundleSchema = exports.exportFinancialSectionSchema = exports.exportUsageReservationSchema = exports.exportLedgerEntrySchema = exports.exportUsageReceiptSchema = exports.exportAttestationSchema = exports.authMethodsResponseSchema = exports.authMethodEntrySchema = exports.domainVerificationInstructionsSchema = exports.domainVerificationRequestSchema = exports.verifiedDomainSchema = exports.signedRecordEnvelopeSchema = exports.didDocumentSchema = exports.didServiceSchema = exports.verificationMethodSchema = exports.appAffinityEventsIngestSchema = exports.appAffinityEventSchema = exports.appAffinityEventTypeSchema = exports.appUserSignalIngestSchema = exports.appInterestInputSchema = exports.appEndorsementInputSchema = exports.recommendationResponseSchema = exports.recommendationItemSchema = exports.recommendationCountSchema = exports.recommendationRequestSchema = exports.recommendationSignalWeightsSchema = void 0;
16
+ exports.conductStandingSchema = exports.conductStrikeStatusSchema = exports.moderationEffectSkipReasonSchema = exports.moderationEffectStatusSchema = exports.moderationEffectTypeSchema = exports.moderationDecisionStatusSchema = exports.moderationAttributionSchema = exports.moderationFindingScopeSchema = exports.moderationSeveritySchema = exports.APPLICATION_MODERATION_STANDINGS = exports.IDENTITY_BINDING_STATUSES = exports.IDENTITY_BINDING_TYPES = exports.PERSONHOOD_STATUSES = exports.CONTRIBUTION_TIERS = exports.CONDUCT_STANDINGS = exports.CONDUCT_STRIKE_STATUSES = exports.MODERATION_EFFECT_SKIP_REASONS = exports.MODERATION_EFFECT_STATUSES = exports.MODERATION_EFFECT_TYPES = exports.MODERATION_DECISION_STATUSES = exports.MODERATION_ATTRIBUTIONS = exports.MODERATION_FINDING_SCOPES = exports.MODERATION_SEVERITIES = exports.isFullReputationBalance = exports.reverseReputationTransactionSchema = exports.upsertReputationRuleSchema = exports.resolveReputationDisputeSchema = exports.createReputationDisputeSchema = exports.awardReputationSchema = exports.reverseReputationTransactionResultSchema = exports.reputationInfluenceResultSchema = exports.reputationLeaderboardEntrySchema = exports.reputationLeaderboardUserSchema = exports.reputationRuleSchema = exports.reputationDisputeSchema = exports.reputationBalanceSchema = exports.reputationBalanceSummarySchema = exports.reputationReliabilitySchema = exports.reputationInfluenceSchema = exports.reputationBalanceBreakdownSchema = exports.reputationTransactionSchema = exports.reputationInfluenceContextSchema = exports.reputationDisputeStatusSchema = exports.reputationTargetEntityTypeSchema = exports.trustTierSchema = exports.reputationTransactionStatusSchema = exports.reputationCategorySchema = exports.REPUTATION_INFLUENCE_CONTEXTS = exports.REPUTATION_DISPUTE_STATUSES = exports.REPUTATION_TARGET_ENTITY_TYPES = void 0;
17
+ exports.BROWSER_HUB_COOKIE_NAME = exports.oauthAuthorizeCodeResponseSchema = exports.oauthConsentDecisionSchema = exports.deviceDirectorySyncSchema = exports.deviceActivateResponseSchema = exports.deviceActivateRequestSchema = exports.deviceDirectorySchema = exports.devicePrincipalSchema = exports.deviceAccountContextSchema = exports.deviceDirectoryProfileSchema = exports.deviceContextRelationshipSchema = exports.sessionAccountsChangedEventSchema = exports.sessionAccountsChangedReasonSchema = exports.SESSION_ACCOUNTS_CHANGED_EVENT = exports.deviceBackgroundTokenResponseSchema = exports.deviceBackgroundTokenRequestSchema = exports.deviceBackgroundCredentialResponseSchema = exports.deviceTokenMintResponseSchema = exports.deviceTokenMintRequestSchema = exports.deviceSessionSyncSchema = exports.activeTokenSchema = exports.deviceSessionStateSchema = exports.sessionAccountSchema = exports.linkPreviewResponseSchema = exports.linkPreviewBatchResponseSchema = exports.linkPreviewBatchRequestSchema = exports.linkPreviewSchema = exports.applicationModerationTrustSchema = exports.reputationContextualInfluenceSchema = exports.reputationReviewingSchema = exports.reputationReportingSchema = exports.reputationConductSchema = exports.reputationContributionSchema = exports.reputationPersonhoodSchema = exports.identityBindingSchema = exports.registerIdentityBindingSchema = exports.reverseModerationEffectResultSchema = exports.applyModerationDecisionResultSchema = exports.moderationEffectSchema = exports.reverseModerationEffectSchema = exports.finalizeModerationDecisionSchema = exports.moderationDecisionEventSchema = exports.moderationPolicyVersionsSchema = exports.moderationDecisionEventSubjectSchema = exports.moderationFindingSchema = exports.applicationModerationStandingSchema = exports.identityBindingStatusSchema = exports.identityBindingTypeSchema = exports.personhoodStatusSchema = exports.contributionTierSchema = void 0;
18
+ exports.webauthnRegisterVerifyRequestSchema = exports.webauthnLoginOptionsRequestSchema = exports.webauthnRegisterOptionsRequestSchema = exports.updateRolloutPatchSchema = exports.promoteRequestSchema = exports.rollbackToEmbeddedRequestSchema = exports.rollbackRequestSchema = exports.updateListResponseSchema = exports.channelListResponseSchema = exports.channelSchema = exports.rollbackToEmbeddedEntrySchema = exports.createUpdateResponseSchema = exports.updateSchema = exports.createUpdateRequestSchema = exports.updateAssetRefSchema = exports.assetCompleteResponseSchema = exports.assetCompleteResultItemSchema = exports.assetCompleteRequestSchema = exports.assetInitResponseSchema = exports.assetUploadTicketSchema = exports.assetInitRequestSchema = exports.assetInitItemSchema = exports.rolloutPercentSchema = exports.runtimeVersionSchema = exports.channelNameSchema = exports.sha256HexSchema = exports.updateAssetStatusSchema = exports.updateStatusSchema = exports.updatePlatformSchema = exports.backupStatusResponseSchema = exports.backupUploadRequestSchema = exports.encryptedBackupEnvelopeSchema = exports.backupLookupIdSchema = exports.rotateKeyCompleteResponseSchema = exports.rotateKeyCompleteRequestSchema = exports.rotateKeyChallengeResponseSchema = exports.loginResultSchema = exports.hubAuthorizeResultSchema = exports.hubAuthorizeRequestSchema = exports.hubActivateRequestSchema = exports.hubClaimRequestSchema = exports.hubSessionSchema = exports.browserHubRevokeResponseSchema = exports.browserHubErrorSchema = exports.browserHubResolveResponseSchema = exports.browserHubHandleResponseSchema = exports.browserHubHandleRequestSchema = exports.browserHubHandleSchema = exports.BROWSER_HUB_HANDLE_TTL_MS = exports.BROWSER_HUB_COOKIE_ATTRIBUTES = void 0;
19
+ exports.authenticatedPrincipalSchema = exports.billingPrincipalSchema = exports.inferenceScopeSchema = exports.INFERENCE_SCOPES = exports.unitPriceSchema = exports.usageQuantitySchema = exports.usageSourceSchema = exports.USAGE_SOURCES = exports.usageUnitSchema = exports.USAGE_UNITS = exports.moneySchema = exports.exactDecimalSchema = exports.INFERENCE_MONEY_SCALE = exports.currencyCodeSchema = exports.RESERVED_ALIA_PUBLISHER = exports.inferenceRegionSchema = exports.deploymentIdSchema = exports.inferenceProviderSlugSchema = exports.routingProfileSlugSchema = exports.modelReferenceSchema = exports.modelRevisionLabelSchema = exports.modelIdSchema = exports.modelSlugSchema = exports.publisherSlugSchema = exports.sha256DigestSchema = exports.inferenceHttpsUrlSchema = exports.inferenceDateSchema = exports.inferenceTimestampSchema = exports.inferenceEnvironmentSchema = exports.idempotencyKeySchema = exports.generationIdSchema = exports.requestIdSchema = exports.oxyCredentialIdSchema = exports.oxyApplicationIdSchema = exports.delegatedUserIdSchema = exports.oxyAccountIdSchema = exports.INFERENCE_CONTRACT_VERSION = exports.transparencyCheckpointListSchema = exports.transparencyInclusionProofSchema = exports.transparencyCheckpointSchema = exports.transparencyAnchorSchema = exports.transparencyCheckpointSignatureSchema = exports.deviceTransferDenyResponseSchema = exports.deviceTransferApproveResponseSchema = exports.deviceTransferApproveRequestSchema = exports.deviceTransferInfoResponseSchema = exports.deviceTransferInitResponseSchema = exports.deviceTransferInitRequestSchema = exports.devicePairingStatusSchema = exports.webauthnLoginVerifyRequestSchema = void 0;
20
+ exports.modelDocumentationSchema = exports.modelReleaseIngestionResultSchema = exports.modelReleaseIngestionRequestSchema = exports.modelLineDeclarationSchema = exports.modelGpaiDocumentationSchema = exports.modelDownstreamDocumentationSchema = exports.SYSTEMIC_RISK_COMPUTE_THRESHOLD_FLOPS = exports.trainingComputeFlopsSchema = exports.modelSystemicRiskTierSchema = exports.modelDistributionMethodSchema = exports.aliaModelReleaseManifestSchema = exports.aliaReleaseSignatureSchema = exports.aliaReleaseArtifactSchema = exports.authorizedRouteSchema = exports.routingPolicyReferenceSchema = exports.routingPolicySchema = exports.routingFallbackPolicySchema = exports.routingPolicyScopeSchema = exports.routingTargetSchema = exports.modelCatalogueEntrySchema = exports.catalogueServingProviderSummarySchema = exports.cataloguePublisherSummarySchema = exports.routingProfileSchema = exports.routingProfileCandidateSchema = exports.modelDeploymentSchema = exports.inferenceProviderSchema = exports.modelRevisionSchema = exports.catalogueModelSchema = exports.modelPublisherSchema = exports.modelSafetyMetadataSchema = exports.modelEvaluationResultSchema = exports.modelDeprecationSchema = exports.commercialPermissionSchema = exports.availabilityScopeSchema = exports.inferenceDataPolicySchema = exports.modelProvenanceSchema = exports.modelLicenseSchema = exports.modelCapabilitiesSchema = exports.inferenceModalitySchema = exports.priceSnapshotSchema = exports.priceVersionSchema = exports.priceVersionStatusSchema = exports.inferenceErrorSchema = exports.providerErrorPassthroughSchema = exports.safeErrorTextSchema = exports.upstreamErrorCategorySchema = exports.inferenceErrorCodeSchema = exports.NON_RETRYABLE_INFERENCE_ERROR_CODES = exports.INFERENCE_ERROR_CODES = exports.inferenceAttributionSchema = void 0;
21
+ exports.externalPaymentProviderSchema = exports.EXTERNAL_PAYMENT_PROVIDERS = exports.billingInvoiceSchema = exports.billingInvoiceStatusSchema = exports.BILLING_INVOICE_STATUSES = exports.accountBillingStateSchema = exports.billingProfileSchema = exports.autoRechargeSchema = exports.billingProfileStatusSchema = exports.BILLING_PROFILE_STATUSES = exports.billingModeSchema = exports.BILLING_MODES = exports.providerConnectionSchema = exports.providerConnectionStatusSchema = exports.providerConnectionValidationSchema = exports.providerSecretReferenceSchema = exports.providerConnectionScopeSchema = exports.PROVIDER_SECRET_REFERENCE_NAMESPACE = exports.usageRefundSchema = exports.usageRefundReasonSchema = exports.usageRefundSubjectSchema = exports.usageReceiptSchema = exports.normalizedUsageReportSchema = exports.inferenceRequestOutcomeSchema = exports.usageReservationSchema = exports.usageReservationStatusSchema = exports.usageReservationRequestSchema = exports.inferenceStreamEventSchema = exports.inferenceStreamDoneEventSchema = exports.inferenceFinishReasonSchema = exports.inferenceStreamErrorEventSchema = exports.inferenceStreamRouteSwitchEventSchema = exports.inferenceRouteSwitchReasonSchema = exports.inferenceRouteSwitchDetailSchema = exports.inferenceStreamUsageEventSchema = exports.inferenceStreamToolCallEventSchema = exports.inferenceStreamDeltaEventSchema = exports.inferenceStreamStartEventSchema = exports.inferenceRequestSchema = exports.clientRequestMetadataSchema = exports.responseFormatSchema = exports.toolChoiceSchema = exports.toolDefinitionSchema = exports.samplingParametersSchema = exports.inferenceInputSchema = exports.inferenceMessageSchema = exports.inferenceMessageRoleSchema = exports.inferenceToolCallSchema = exports.inferenceContentPartSchema = exports.inferenceContentSourceSchema = void 0;
22
+ exports.productEntitlementSchema = exports.costCenterSpendSchema = exports.costCenterSchema = exports.costCenterStatusSchema = exports.COST_CENTER_STATUSES = exports.payAsYouGoEntitlementSchema = exports.productPlanSchema = exports.planAllowanceSchema = exports.LIVE_PRODUCT_PLAN_STATUSES = exports.productPlanStatusSchema = exports.PRODUCT_PLAN_STATUSES = exports.reconciliationReportSchema = exports.reconciliationRunSchema = exports.reconciliationDiscrepancySchema = exports.reconciliationRunStatusSchema = exports.RECONCILIATION_RUN_STATUSES = exports.reconciliationDiscrepancyKindSchema = exports.RECONCILIATION_DISCREPANCY_KINDS = exports.autoRechargeAttemptSchema = exports.autoRechargeStatusSchema = exports.AUTO_RECHARGE_STATUSES = exports.externalPaymentSchema = exports.externalPaymentKindSchema = exports.EXTERNAL_PAYMENT_KINDS = void 0;
23
23
  var accountGraph_1 = require("./accountGraph");
24
24
  Object.defineProperty(exports, "ACCOUNT_KINDS", { enumerable: true, get: function () { return accountGraph_1.ACCOUNT_KINDS; } });
25
25
  Object.defineProperty(exports, "accountKindSchema", { enumerable: true, get: function () { return accountGraph_1.accountKindSchema; } });
26
26
  Object.defineProperty(exports, "CHILD_ACCOUNT_KINDS", { enumerable: true, get: function () { return accountGraph_1.CHILD_ACCOUNT_KINDS; } });
27
27
  Object.defineProperty(exports, "childAccountKindSchema", { enumerable: true, get: function () { return accountGraph_1.childAccountKindSchema; } });
28
28
  Object.defineProperty(exports, "isAccountKind", { enumerable: true, get: function () { return accountGraph_1.isAccountKind; } });
29
- Object.defineProperty(exports, "isActAsEligibleKind", { enumerable: true, get: function () { return accountGraph_1.isActAsEligibleKind; } });
29
+ Object.defineProperty(exports, "isDelegatedActAsEligibleKind", { enumerable: true, get: function () { return accountGraph_1.isDelegatedActAsEligibleKind; } });
30
+ Object.defineProperty(exports, "isOperatorSwitchTargetKind", { enumerable: true, get: function () { return accountGraph_1.isOperatorSwitchTargetKind; } });
30
31
  Object.defineProperty(exports, "ACCOUNT_CATEGORY_IDS", { enumerable: true, get: function () { return accountGraph_1.ACCOUNT_CATEGORY_IDS; } });
31
32
  Object.defineProperty(exports, "ACCOUNT_CATEGORY_KINDS", { enumerable: true, get: function () { return accountGraph_1.ACCOUNT_CATEGORY_KINDS; } });
32
33
  Object.defineProperty(exports, "accountCategoriesSchema", { enumerable: true, get: function () { return accountGraph_1.accountCategoriesSchema; } });
@@ -38,6 +39,13 @@ Object.defineProperty(exports, "newlyAddedRetiredCategories", { enumerable: true
38
39
  Object.defineProperty(exports, "RETIRED_ACCOUNT_CATEGORY_IDS", { enumerable: true, get: function () { return accountGraph_1.RETIRED_ACCOUNT_CATEGORY_IDS; } });
39
40
  Object.defineProperty(exports, "SELECTABLE_ACCOUNT_CATEGORY_IDS", { enumerable: true, get: function () { return accountGraph_1.SELECTABLE_ACCOUNT_CATEGORY_IDS; } });
40
41
  Object.defineProperty(exports, "createAccountRequestSchema", { enumerable: true, get: function () { return accountGraph_1.createAccountRequestSchema; } });
42
+ var username_1 = require("./username");
43
+ Object.defineProperty(exports, "usernameSchema", { enumerable: true, get: function () { return username_1.usernameSchema; } });
44
+ Object.defineProperty(exports, "isValidUsername", { enumerable: true, get: function () { return username_1.isValidUsername; } });
45
+ Object.defineProperty(exports, "stripDisallowedUsernameCharacters", { enumerable: true, get: function () { return username_1.stripDisallowedUsernameCharacters; } });
46
+ Object.defineProperty(exports, "USERNAME_MIN_LENGTH", { enumerable: true, get: function () { return username_1.USERNAME_MIN_LENGTH; } });
47
+ Object.defineProperty(exports, "USERNAME_MAX_LENGTH", { enumerable: true, get: function () { return username_1.USERNAME_MAX_LENGTH; } });
48
+ Object.defineProperty(exports, "USERNAME_INVALID_MESSAGE", { enumerable: true, get: function () { return username_1.USERNAME_INVALID_MESSAGE; } });
41
49
  var userResponse_1 = require("./userResponse");
42
50
  // Schemas
43
51
  Object.defineProperty(exports, "userNameSchema", { enumerable: true, get: function () { return userResponse_1.userNameSchema; } });
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ /**
3
+ * Username policy — the ONE rule, for every kind of account.
4
+ *
5
+ * A username is a HANDLE: the routing key of a profile URL (`/@alice`), the
6
+ * local part of a webfinger `acct:`, and a login identifier. `users.username`
7
+ * carries a single unique index, `lower(btrim(username))`, and people, bots,
8
+ * organizations, projects and channels all draw from it. There is no per-kind
9
+ * namespace, so there is no per-kind rule — a bot that may reserve a name a
10
+ * person cannot ask for is a disagreement inside one index, not a variant.
11
+ *
12
+ * ## Why this file exists
13
+ *
14
+ * Seven rules governed this one namespace: four validators (this package's
15
+ * predecessor in `@oxyhq/api`, `@oxyhq/core`, `@oxyhq/commons`, and one written
16
+ * inline in `AccountService.resolveUniqueUsername`) and three that COERCED —
17
+ * silently deleting the characters they disliked, which hands somebody an
18
+ * account under a name they never chose. They lived in five packages and no test
19
+ * asserted they agreed. `contracts` is where the single declaration can actually
20
+ * live: `api`, `core`, `commons`, `services` and `auth` all already depend on it,
21
+ * so every write path can IMPORT the rule instead of restating it.
22
+ * `__tests__/usernamePolicySingleSource.test.ts` fails if a second one appears.
23
+ *
24
+ * ## The rule, and why each part of it
25
+ *
26
+ * ```
27
+ * 3–30 characters
28
+ * first and last character: [A-Za-z0-9]
29
+ * interior: [A-Za-z0-9_-]
30
+ * never two separators in a row
31
+ * ```
32
+ *
33
+ * - **Hyphens are admitted because the DATABASE already admits them.**
34
+ * `internal_cost_centers_slug_check` is a CHECK constraint —
35
+ * `^[a-z0-9][a-z0-9-]{0,62}$` — and `seed-internal-cost-centers` mints a
36
+ * `project` account whose username IS the slug; four of the five declared
37
+ * centres contain a hyphen. An alphanumeric-only handle rule would contradict
38
+ * a constraint written to permit them, and would make those centres
39
+ * unmintable. This is the argument, not the four hyphenated accounts that
40
+ * happen to exist — they are a symptom.
41
+ * - **Dots are NOT admitted.** A dot is the delimiter that separates handle from
42
+ * domain in the federated form this same column stores for remote actors
43
+ * (`alice@mastodon.social`), it collides with extension-style routing
44
+ * (`/@alice.json`), and `n.ate` beside `nate` is the strongest confusable pair
45
+ * an ASCII handle can produce. Only the inline account rule ever accepted one,
46
+ * and it accepted it by accident: its `[\w.-]` was written for a SLUG.
47
+ * - **A length bound, always.** The account path had none — the only ceiling was
48
+ * a `.max(100)` on the wire schema. 3 is the floor because `oxy`, the platform
49
+ * owner's own organization, is three characters. 30 is the ceiling four of the
50
+ * seven rules and the availability endpoint already published.
51
+ * - **First and last character alphanumeric, and no `--` / `__` / `-_` run.**
52
+ * Both are free — no account uses such a name — and they remove the
53
+ * confusable shapes that admitting two separators would otherwise introduce.
54
+ *
55
+ * ## Case, and what this schema deliberately does not do
56
+ *
57
+ * **Case is PRESERVED.** Uniqueness is decided by the database's
58
+ * `lower(btrim(username))` index, so `Alice` and `alice` cannot coexist, but a
59
+ * name that was typed with a capital keeps it. This schema therefore never
60
+ * lower-cases: rewriting a caller's input is how `resolveUniqueUsername` used to
61
+ * return `mybot` to somebody who asked for `MyBot`.
62
+ *
63
+ * **This is a WRITE-path rule.** It states what may be newly stored, not what may
64
+ * be read. Rows that predate it — including 11 with no username at all — must go
65
+ * on loading, resolving and rendering; validating on a read turns an existing
66
+ * account into a 500.
67
+ *
68
+ * **It does not govern remote actors.** The same column holds ~73k federated
69
+ * rows in `handle@domain` form, written by `POST /users/resolve` through its own
70
+ * normalizer. Those are another server's namespace; this rule would reject every
71
+ * one of them and must never be pointed at that path.
72
+ *
73
+ * ## Usable by a handle GENERATOR, deliberately
74
+ *
75
+ * Slug generators are how the eighth copy of this rule appears. Alia's
76
+ * `suggestAgentUsername` builds one from an agent's name and re-derives a subset
77
+ * of these rules by hand — its own docblock admits it ("A leading digit or an
78
+ * empty slug both fail Oxy's username rules") — and, having no minimum, proposes
79
+ * `al` for an agent called "Al", which the server then refuses.
80
+ *
81
+ * So this module answers a generator's three questions without dragging a server
82
+ * dependency along. It is zod and nothing else, so it imports cleanly into a
83
+ * React Native bundle or another repo's backend:
84
+ *
85
+ * - *Does this candidate pass?* {@link isValidUsername}, or `safeParse` when the
86
+ * reason matters.
87
+ * - *How short is too short, how long is too long?* {@link USERNAME_MIN_LENGTH}
88
+ * and {@link USERNAME_MAX_LENGTH}, so a generator can pad or truncate instead
89
+ * of guessing and being 400ed.
90
+ * - *Which characters survive?* {@link stripDisallowedUsernameCharacters}.
91
+ *
92
+ * A generator PROPOSES; only `POST /accounts` decides, and a taken handle comes
93
+ * back as a 409 for the client to retry with a fresh suggestion. Nothing here
94
+ * knows what is taken, and it must not pretend to.
95
+ */
96
+ Object.defineProperty(exports, "__esModule", { value: true });
97
+ exports.usernameSchema = exports.USERNAME_PATTERN_SOURCE = exports.USERNAME_INVALID_MESSAGE = exports.USERNAME_MAX_LENGTH = exports.USERNAME_MIN_LENGTH = void 0;
98
+ exports.isValidUsername = isValidUsername;
99
+ exports.stripDisallowedUsernameCharacters = stripDisallowedUsernameCharacters;
100
+ const zod_1 = require("zod");
101
+ /** Shortest storable handle. `oxy` sets the floor. */
102
+ exports.USERNAME_MIN_LENGTH = 3;
103
+ /** Longest storable handle, and the `maxLength` an input field should carry. */
104
+ exports.USERNAME_MAX_LENGTH = 30;
105
+ /** The 400 / inline-validation copy for every path that rejects a handle. */
106
+ exports.USERNAME_INVALID_MESSAGE = 'Username must be 3-30 characters, use only letters, numbers, hyphens and underscores, ' +
107
+ 'start and end with a letter or number, and never repeat a separator';
108
+ /**
109
+ * Alphanumeric runs joined by single separators, as a SOURCE string.
110
+ *
111
+ * A string rather than a literal because the OpenAPI docblocks that publish this
112
+ * rule (`POST /auth/register`, `PUT /users/:userId`) must quote it verbatim, and
113
+ * `usernamePolicySingleSource.test.ts` compares them against THIS constant. A
114
+ * published `pattern:` that drifts from the enforced rule is a lie told to every
115
+ * client that generates from the spec, and it is exactly the kind of copy nobody
116
+ * notices going stale.
117
+ *
118
+ * Deliberately NOT re-exported from the package barrel: it exists for the
119
+ * schema below and for that one gate. Anything validating a username uses
120
+ * {@link usernameSchema}, so there is no second way to ask the question.
121
+ *
122
+ * Written as an unambiguous alternation rather than a lookahead: every character
123
+ * belongs to exactly one branch, so matching is linear and there is no
124
+ * backtracking to bound. It also carries no `\p{…}` property escape, which
125
+ * mobile Hermes throws on at runtime — this module is reachable from every React
126
+ * Native consumer.
127
+ */
128
+ exports.USERNAME_PATTERN_SOURCE = '^[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*$';
129
+ const USERNAME_PATTERN = new RegExp(exports.USERNAME_PATTERN_SOURCE);
130
+ /**
131
+ * The one username policy, as a schema.
132
+ *
133
+ * `.trim()` first, so surrounding whitespace is a typo rather than a rejection —
134
+ * but interior whitespace is NOT removed. It falls to the pattern, because
135
+ * squashing `"al ice"` into `"alice"` would hand the user an account under a name
136
+ * they never chose. Every write path validates through THIS object; nothing
137
+ * re-implements it.
138
+ */
139
+ exports.usernameSchema = zod_1.z
140
+ .string()
141
+ .trim()
142
+ .min(exports.USERNAME_MIN_LENGTH, exports.USERNAME_INVALID_MESSAGE)
143
+ .max(exports.USERNAME_MAX_LENGTH, exports.USERNAME_INVALID_MESSAGE)
144
+ .regex(USERNAME_PATTERN, exports.USERNAME_INVALID_MESSAGE);
145
+ /**
146
+ * Whether a candidate handle is storable — the boolean form, for input surfaces
147
+ * that show a message as somebody types rather than throwing.
148
+ *
149
+ * Answers from {@link usernameSchema}, so a client's inline check and the
150
+ * server's 400 cannot disagree.
151
+ */
152
+ function isValidUsername(candidate) {
153
+ return exports.usernameSchema.safeParse(candidate).success;
154
+ }
155
+ /**
156
+ * Drop the characters the policy forbids, for an input field that filters
157
+ * keystrokes.
158
+ *
159
+ * This is a TYPING aid and nothing else — the result still has to pass
160
+ * {@link usernameSchema}, which is what decides. It does not lower-case (case is
161
+ * preserved, see the header) and it cannot repair a name: a value that is too
162
+ * short, edge-separated or doubly-separated comes back unchanged and fails
163
+ * validation with a message, which is the outcome the coercing rules this
164
+ * replaces used to hide.
165
+ */
166
+ function stripDisallowedUsernameCharacters(input) {
167
+ return input.replace(/[^A-Za-z0-9_-]/g, '');
168
+ }