@ttt-productions/ttt-core 0.79.86 → 0.79.88
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.
- package/dist/doc-schemas/content.d.ts +1 -0
- package/dist/doc-schemas/content.d.ts.map +1 -1
- package/dist/doc-schemas/content.js +2 -1
- package/dist/doc-schemas/content.js.map +1 -1
- package/dist/doc-schemas/registry.d.ts +1 -0
- package/dist/doc-schemas/registry.d.ts.map +1 -1
- package/dist/media/upload-tray-display.d.ts +16 -12
- package/dist/media/upload-tray-display.d.ts.map +1 -1
- package/dist/media/upload-tray-display.js +13 -72
- package/dist/media/upload-tray-display.js.map +1 -1
- package/dist/utils/hall-content.d.ts +104 -1
- package/dist/utils/hall-content.d.ts.map +1 -1
- package/dist/utils/hall-content.js +13 -1
- package/dist/utils/hall-content.js.map +1 -1
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +0 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/utils/format.d.ts +0 -6
- package/dist/utils/format.d.ts.map +0 -1
- package/dist/utils/format.js +0 -19
- package/dist/utils/format.js.map +0 -1
|
@@ -131,6 +131,7 @@ export declare const ThresholdItemSchema: z.ZodObject<{
|
|
|
131
131
|
attestNoCredits: z.ZodLiteral<true>;
|
|
132
132
|
attestNoBegging: z.ZodLiteral<true>;
|
|
133
133
|
attestHumanMadeOriginal: z.ZodLiteral<true>;
|
|
134
|
+
attestPublishStewardship: z.ZodLiteral<true>;
|
|
134
135
|
attestedAt: z.ZodNumber;
|
|
135
136
|
legalReviewNotice: z.ZodOptional<z.ZodObject<{
|
|
136
137
|
revision: z.ZodString;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/content.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA4BxB,eAAO,MAAM,cAAc;;;;EAA2D,CAAC;AACvF,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAStD,eAAO,MAAM,cAAc;;;;;;;iBAOzB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;iBAW5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,cAAc;;;;;;;iBAOzB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;iBAY9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,oBAAoB;;;;;;;iBAO/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;iBAYtC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAIhF;;kFAEkF;AAClF,eAAO,MAAM,+BAA+B;;;kBAGjC,CAAC;AACZ,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAExF,eAAO,MAAM,mBAAmB
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/content.ts"],"names":[],"mappings":"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"}
|
|
@@ -119,12 +119,13 @@ export const ThresholdItemSchema = z.object({
|
|
|
119
119
|
// (REAL_PEOPLE_DISCLAIMER_MESSAGE) — there is no free-text disclaimer anywhere.
|
|
120
120
|
hasRealPeople: z.boolean(),
|
|
121
121
|
// Submission attestations — REQUIRED. The submit core refuses a submission unless the artisan
|
|
122
|
-
// ticks all
|
|
122
|
+
// ticks all five, then stores each as the literal `true` with the moment they were given. A
|
|
123
123
|
// threshold item without them is not a valid submission.
|
|
124
124
|
attestConsistentFormat: z.literal(true),
|
|
125
125
|
attestNoCredits: z.literal(true),
|
|
126
126
|
attestNoBegging: z.literal(true),
|
|
127
127
|
attestHumanMadeOriginal: z.literal(true),
|
|
128
|
+
attestPublishStewardship: z.literal(true),
|
|
128
129
|
attestedAt: z.number(),
|
|
129
130
|
// The founder legal-review notice acknowledgment given with the attestations, written in the
|
|
130
131
|
// same submission transaction. Present while the notice is active (the submit core refuses a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/doc-schemas/content.ts"],"names":[],"mappings":"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","sourcesContent":["// Content Firestore document SCHEMAS — Tales/Tunes/Television sub-documents, the\n// Threshold + Hall library item shapes, Hall library user preferences, and the\n// `_config` singleton docs (futurePlans, rulesAndAgreements). Types are inferred via\n// z.infer. The enum-key consts (HALL_WING_TYPE_KEYS / WORK_PROJECT_TYPE_KEYS) and the\n// UI-only filter/view types remain in ../types/content.ts.\n\nimport { z } from 'zod';\nimport { HALL_WING_TYPE_KEYS, RULE_GROUP_KEYS, WORK_PROJECT_TYPE_KEYS } from '../types/content.js';\nimport {\n ModerationDecisionNumberSchema,\n ModerationEdgeSyncOpSchema,\n ModerationEdgeSyncStateSchema,\n ModerationHiddenBySchema,\n} from './moderation.js';\nimport { MAX_THRESHOLD_PUBLISH_PARKED_REASON_LENGTH } from '../constants/business-admin.js';\nimport { FIRESTORE_INDEXED_VALUE_MAX_BYTES } from '../constants/business-platform.js';\nimport { LegalReviewNoticeReceiptSchema } from './legal-review-notice.js';\nimport {\n HALL_CONTENT_DETAIL_SURFACES,\n HALL_CONTENT_SUB_ITEM_SURFACES,\n} from '../constants/hall-content-routing.js';\n\nconst contentStatusSchema = z.enum(['unpublished', 'pending_approval', 'published']);\n\n// Per-field moderation text-clear remedy on the in-Work chapter / track / episode sub-items (the\n// published Hall projections declare the same two fields). `moderationClearedFields` lists which\n// text fields (e.g. 'title', 'description', 'content') an admin cleared to a neutral placeholder\n// and which now await steward re-entry; empty/absent when nothing was cleared. `moderationClearedReason` is the operator's reason, surfaced on the member's\n// edit surface. Extends the workProject/workRealm placeholder remedy per-field. Backend-only-writable.\nconst moderationClearedFieldsShape = {\n moderationClearedFields: z.array(z.string()).optional(),\n moderationClearedReason: z.string().optional(),\n};\n\nexport const ItemsKeySchema = z.enum(['tuneTracks', 'chapters', 'televisionEpisodes']);\nexport type ItemsKey = z.infer<typeof ItemsKeySchema>;\n\n// --- WorkProject content sub-docs ---\n\n// A Work has ONE title and ONE description, typed on the Work itself (`workingTitle` /\n// `workingDescription`); the Tale / Tune / Television section doc carries no text of its own —\n// only the covers and genres the Hall entry publishes beside the Work's text. Chapters, tracks,\n// and episodes keep their own titles and text.\n\nexport const FullTaleSchema = z.object({\n uid: z.string(),\n createdOn: z.number(),\n coverSquareAssetId: z.string().optional(),\n coverPosterAssetId: z.string().optional(),\n coverCinematicAssetId: z.string().optional(),\n workGenres: z.array(z.string()).optional(),\n});\nexport type FullTale = z.infer<typeof FullTaleSchema>;\n\nexport const FullChapterSchema = z.object({\n uid: z.string(),\n title: z.string(),\n content: z.string(),\n description: z.string(),\n order: z.number(),\n photoAssetId: z.string().optional(),\n status: contentStatusSchema,\n createdOn: z.number(),\n ...moderationClearedFieldsShape,\n moderatedAt: z.number().optional(),\n});\nexport type FullChapter = z.infer<typeof FullChapterSchema>;\n\nexport const FullTuneSchema = z.object({\n uid: z.string(),\n coverSquareAssetId: z.string().optional(),\n coverPosterAssetId: z.string().optional(),\n coverCinematicAssetId: z.string().optional(),\n workGenres: z.array(z.string()),\n createdOn: z.number(),\n});\nexport type FullTune = z.infer<typeof FullTuneSchema>;\n\nexport const FullTuneTrackSchema = z.object({\n uid: z.string(),\n title: z.string(),\n description: z.string().optional(),\n audioAssetId: z.string().optional(),\n mediaType: z.string().optional(),\n order: z.number(),\n photoAssetId: z.string().optional(),\n status: contentStatusSchema,\n createdOn: z.number(),\n ...moderationClearedFieldsShape,\n moderatedAt: z.number().optional(),\n});\nexport type FullTuneTrack = z.infer<typeof FullTuneTrackSchema>;\n\nexport const FullTelevisionSchema = z.object({\n uid: z.string(),\n createdOn: z.number(),\n coverSquareAssetId: z.string().optional(),\n coverPosterAssetId: z.string().optional(),\n coverCinematicAssetId: z.string().optional(),\n workGenres: z.array(z.string()),\n});\nexport type FullTelevision = z.infer<typeof FullTelevisionSchema>;\n\nexport const FullTelevisionEpisodeSchema = z.object({\n uid: z.string(),\n title: z.string(),\n description: z.string().optional(),\n videoAssetId: z.string(),\n mediaType: z.string().optional(),\n order: z.number(),\n photoAssetId: z.string().optional(),\n status: contentStatusSchema,\n createdOn: z.number(),\n ...moderationClearedFieldsShape,\n moderatedAt: z.number().optional(),\n});\nexport type FullTelevisionEpisode = z.infer<typeof FullTelevisionEpisodeSchema>;\n\n// --- Threshold + Hall library items ---\n\n/** `allWorkProjects/{workProjectId}/hallSubmissionReservation/reservation` — the Work's ONE\n * hall-entry reservation, created (never updated) inside the first threshold submit's\n * transaction; every later submit converges on its `hallItemId`. Backend-only. */\nexport const HallSubmissionReservationSchema = z.object({\n hallItemId: z.string().min(1),\n createdAt: z.number(),\n}).strict();\nexport type HallSubmissionReservation = z.infer<typeof HallSubmissionReservationSchema>;\n\nexport const ThresholdItemSchema = z.object({\n thresholdItemId: z.string(),\n hallItemId: z.string(),\n workProjectId: z.string(),\n workProjectType: z.enum(WORK_PROJECT_TYPE_KEYS),\n itemId: z.string(),\n itemsKey: ItemsKeySchema,\n order: z.number(),\n hallWingType: z.enum(HALL_WING_TYPE_KEYS),\n submittedAt: z.number(),\n reviewStatus: z.enum(['pending', 'needs_revision', 'approved']),\n adminNotes: z.string().optional(),\n reviewedAt: z.number().optional(),\n reviewedBy: z.string().optional(),\n // Parody / real-people AUTHOR ATTESTATION (R3, 2026-07-12). The submitting artisan\n // attests at threshold SUBMIT time that this work depicts real people (parody /\n // satire / commentary); stored with the submission and displayed READ-ONLY to the\n // reviewer. Admins never set or edit it — a reviewer who believes the flag is\n // needed and missing sends the item back needs-revision. The disclaimer shown on\n // published items is the ONE standard platform message\n // (REAL_PEOPLE_DISCLAIMER_MESSAGE) — there is no free-text disclaimer anywhere.\n hasRealPeople: z.boolean(),\n // Submission attestations — REQUIRED. The submit core refuses a submission unless the artisan\n // ticks all four, then stores each as the literal `true` with the moment they were given. A\n // threshold item without them is not a valid submission.\n attestConsistentFormat: z.literal(true),\n attestNoCredits: z.literal(true),\n attestNoBegging: z.literal(true),\n attestHumanMadeOriginal: z.literal(true),\n attestedAt: z.number(),\n // The founder legal-review notice acknowledgment given with the attestations, written in the\n // same submission transaction. Present while the notice is active (the submit core refuses a\n // submission without the checkbox then); absent when the notice is off.\n legalReviewNotice: LegalReviewNoticeReceiptSchema.optional(),\n // Reviewer confirmations — stamped `true` together by the APPROVAL write and never otherwise,\n // so their presence means the item was approved with all four checks confirmed.\n confirmedNoBegging: z.literal(true).optional(),\n confirmedNoCredits: z.literal(true).optional(),\n confirmedConsistentFormat: z.literal(true).optional(),\n confirmedRealPeopleAttestation: z.literal(true).optional(),\n // Terminal publish PARK. An approved item whose publish stops without publishing (source media\n // ineligible, a blocking safety hold, a moderation hide landing after approval, an invalid work\n // type) leaves the threshold doc + admin task in place for operator intervention. The reason was\n // only ever visible in Sentry and the `system.manualIntervention` audit event; stamping it here\n // is what lets the admin review work view say WHY the item is sitting there. Optional because\n // only a park stamps it, and `reviewStatus` keeps its meaning — a park is not a new status.\n publishParkedReason: z.string().max(MAX_THRESHOLD_PUBLISH_PARKED_REASON_LENGTH).optional(),\n publishParkedAt: z.number().optional(),\n});\nexport type ThresholdItem = z.infer<typeof ThresholdItemSchema>;\n\n// --- Published change requests (launch: text-only) ---\n\n/** The published hall-content surfaces whose TEXT fields a change request (and the\n * moderation text-clear remedy) can target. Detail surfaces live on the hall parent;\n * sub-item surfaces on the published chapter/track/episode doc; the `workRealm`\n * surface targets the single `workRealms/{id}` doc (the realm grain of the one\n * text-change pipeline — R1, 2026-07-12). */\nexport const HallContentTextSurfaceSchema = z.enum([\n ...HALL_CONTENT_DETAIL_SURFACES,\n ...HALL_CONTENT_SUB_ITEM_SURFACES,\n 'workRealm',\n]);\nexport type HallContentTextSurface = z.infer<typeof HallContentTextSurfaceSchema>;\n\n/** The ONE canonical hall sub-item kind (a Tale chapter / Tune track / Television\n * episode) as carried on notification metadata and Streetz post payloads. Distinct\n * from `HallContentTextSurfaceSchema` (which keys text-change surfaces and uses the\n * compound `tuneTrack`/`televisionEpisode` identifiers). Never re-declare inline. */\nexport const HallSubItemTypeSchema = z.enum(['chapter', 'track', 'episode']);\nexport type HallSubItemType = z.infer<typeof HallSubItemTypeSchema>;\n\n/** The ONE canonical published-hall-item lifecycle status. */\nexport const PublishedHallItemStatusSchema = z.enum(['published', 'paused', 'banned']);\nexport type PublishedHallItemStatus = z.infer<typeof PublishedHallItemStatusSchema>;\n\n/** A change request's stored `targetKey`: non-empty, and short enough for its equality query to\n * be exact (an indexed value past Firestore's limit is truncated in the index). */\nexport const hallContentChangeRequestTargetKeySchema = z\n .string()\n .min(1)\n .refine((key) => new TextEncoder().encode(key).length <= FIRESTORE_INDEXED_VALUE_MAX_BYTES, {\n message: 'A change-request target key is longer than Firestore indexes exactly.',\n });\n\n// A member's proposal to change TEXT fields on a PUBLISHED hall item (Ruling 2 of the\n// admin-work-correspondence order). The live published item is NEVER unlocked and never\n// edited by the member — this doc carries the PROPOSED values only; OLD values render\n// live from the published docs. Approve = server writes the values onto the published\n// item + its live in-Work source doc; deny = nothing changes, `resolutionReason` shown\n// to the member. Writes are callable-only; reads are the owning work's active guildmates\n// + admins. `requestKind` future-proofs a media variant (new kind, no schema break).\nexport const HallContentChangeRequestSchema = z.object({\n changeRequestId: z.string(),\n requestKind: z.literal('text'),\n // One-open-per-target enforcement/query key, built only by `hallContentChangeRequestTargetKey`\n // (Hall grains) and `workRealmChangeRequestTargetKey` (realm grain).\n targetKey: hallContentChangeRequestTargetKeySchema,\n // null ⇒ the workRealm grain (no hall item involved).\n hallItemId: z.string().nullable(),\n // Always set. On the workRealm grain this is the realm's foundingWorkProjectId\n // (server-derived) so the owner list read, rules, and admin-task fields keep\n // one uniform key across all grains.\n workProjectId: z.string(),\n // null ⇒ the workRealm grain (a realm has no work-project type).\n workProjectType: z.enum(WORK_PROJECT_TYPE_KEYS).nullable(),\n surface: HallContentTextSurfaceSchema,\n // Set ⇒ the workRealm grain; null on the hall grains.\n workRealmId: z.string().nullable(),\n // null ⇒ the hall parent DETAIL (or the workRealm grain); set ⇒ a\n // chapter/track/episode sub-item.\n subItemId: z.string().nullable(),\n proposerUid: z.string(),\n // Raw doc field name → proposed new text. The top-level `surface` is the single\n // authoritative discriminator; the allowlist and each field's declaration are enforced at\n // the backend boundary by `validateHallContentTextFields` (HALL_CONTENT_TEXT_FIELDS,\n // HALL_CONTENT_CHANGE_REQUEST_INPUTS).\n proposedFields: z.record(z.string(), z.string()),\n status: z.enum(['requested', 'approved', 'denied']),\n createdAt: z.number(),\n lastUpdatedAt: z.number(),\n resolvedAt: z.number().optional(),\n resolvedBy: z.string().optional(),\n // Admin's reason, surfaced to the member (required on a deny).\n resolutionReason: z.string().optional(),\n});\nexport type HallContentChangeRequest = z.infer<typeof HallContentChangeRequestSchema>;\n\nexport const PublishedHallItemSchema = z.object({\n hallItemId: z.string(),\n workProjectId: z.string(),\n workProjectType: z.enum(WORK_PROJECT_TYPE_KEYS),\n status: PublishedHallItemStatusSchema,\n createdOn: z.number(),\n publishedAt: z.number().optional(),\n hallWingType: z.enum(HALL_WING_TYPE_KEYS),\n title: z.string().optional(),\n description: z.string().optional(),\n // REQUIRED on the published hall parent: all three covers are a publish-readiness rule, so a\n // published entry always carries every one. The working/draft section docs (FullTale / FullTune /\n // FullTelevision) keep them optional — that is where covers are uploaded one at a time.\n coverSquareAssetId: z.string().min(1),\n coverPosterAssetId: z.string().min(1),\n coverCinematicAssetId: z.string().min(1),\n workGenres: z.array(z.string()).optional(),\n followerCount: z.number().optional(),\n hidden: z.boolean(),\n // Whether the current hide was applied DIRECTly to this item or propagated by a moderation\n // CASCADE from a parent (realm/work). Absent when not hidden. Backend-only-writable.\n hiddenBy: ModerationHiddenBySchema.optional(),\n // Moderation text-clear remedy (extends the workProject/workRealm placeholder family, per-field):\n // which text fields an admin cleared to a neutral placeholder and now await steward re-entry\n // (e.g. ['title', 'description']). Empty/absent when nothing was cleared. `moderationClearedReason`\n // is the operator's reason (shown on the steward's edit surface). Backend-only-writable.\n moderationClearedFields: z.array(z.string()).optional(),\n moderationClearedReason: z.string().optional(),\n moderatedAt: z.number().optional(),\n // Parody / real-people flag (carried from the approved ThresholdItem's AUTHOR\n // attestation — R3, 2026-07-12). When true, display surfaces render the ONE\n // standard platform message (REAL_PEOPLE_DISCLAIMER_MESSAGE) prominently on the\n // published Work — never a stored free-text disclaimer. Backend-written at publish.\n hasRealPeople: z.boolean().optional(),\n});\nexport type PublishedHallItem = z.infer<typeof PublishedHallItemSchema>;\n\nexport const PublishedTuneTrackSchema = z.object({\n uid: z.string(),\n title: z.string(),\n order: z.number(),\n description: z.string().optional(),\n // REQUIRED on a published sub-item (HALL_SUB_ITEM_REQUIRED_FIELDS_BY_WORK_TYPE.Tunes): a track\n // reaches the Hall only with its audio and its picture. The working `FullTuneTrack` keeps both\n // optional — that shape has to be able to represent incomplete content.\n audioAssetId: z.string().min(1),\n photoAssetId: z.string().min(1),\n hidden: z.boolean(),\n // Direct hide vs cascade-from-parent (see PublishedHallItemSchema). Absent when not hidden.\n hiddenBy: ModerationHiddenBySchema.optional(),\n // Per-field moderation text-clear remedy (see PublishedHallItemSchema): which text fields were\n // cleared to a neutral placeholder and await steward re-entry, plus the operator's reason.\n moderationClearedFields: z.array(z.string()).optional(),\n moderationClearedReason: z.string().optional(),\n moderatedAt: z.number().optional(),\n edgeSyncState: ModerationEdgeSyncStateSchema.nullable().optional(),\n edgeSyncProcessingAt: z.number().optional(),\n edgeSyncOp: ModerationEdgeSyncOpSchema.optional(),\n edgeSyncDecision: ModerationDecisionNumberSchema.optional(),\n edgeSyncAssetIds: z.array(z.string().min(1)).optional(),\n edgeSyncError: z.string().optional(),\n edgeSyncFailedAt: z.number().optional(),\n});\nexport type PublishedTuneTrack = z.infer<typeof PublishedTuneTrackSchema>;\n\nexport const PublishedChapterSchema = z.object({\n uid: z.string(),\n title: z.string(),\n order: z.number(),\n description: z.string().optional(),\n content: z.string(),\n // REQUIRED on a published sub-item (HALL_SUB_ITEM_REQUIRED_FIELDS_BY_WORK_TYPE.Tales); the\n // working `FullChapter` keeps it optional.\n photoAssetId: z.string().min(1),\n hidden: z.boolean(),\n // Direct hide vs cascade-from-parent (see PublishedHallItemSchema). Absent when not hidden.\n hiddenBy: ModerationHiddenBySchema.optional(),\n // Per-field moderation text-clear remedy (see PublishedHallItemSchema): which text fields were\n // cleared to a neutral placeholder and await steward re-entry, plus the operator's reason.\n moderationClearedFields: z.array(z.string()).optional(),\n moderationClearedReason: z.string().optional(),\n moderatedAt: z.number().optional(),\n edgeSyncState: ModerationEdgeSyncStateSchema.nullable().optional(),\n edgeSyncProcessingAt: z.number().optional(),\n edgeSyncOp: ModerationEdgeSyncOpSchema.optional(),\n edgeSyncDecision: ModerationDecisionNumberSchema.optional(),\n edgeSyncAssetIds: z.array(z.string().min(1)).optional(),\n edgeSyncError: z.string().optional(),\n edgeSyncFailedAt: z.number().optional(),\n});\nexport type PublishedChapter = z.infer<typeof PublishedChapterSchema>;\n\nexport const PublishedTelevisionEpisodeSchema = z.object({\n uid: z.string(),\n title: z.string(),\n order: z.number(),\n description: z.string().optional(),\n // REQUIRED on a published sub-item (HALL_SUB_ITEM_REQUIRED_FIELDS_BY_WORK_TYPE.Television): an\n // episode reaches the Hall only with its video and its picture. The working\n // `FullTelevisionEpisode` keeps the picture optional.\n videoAssetId: z.string().min(1),\n photoAssetId: z.string().min(1),\n hidden: z.boolean(),\n // Direct hide vs cascade-from-parent (see PublishedHallItemSchema). Absent when not hidden.\n hiddenBy: ModerationHiddenBySchema.optional(),\n // Per-field moderation text-clear remedy (see PublishedHallItemSchema): which text fields were\n // cleared to a neutral placeholder and await steward re-entry, plus the operator's reason.\n moderationClearedFields: z.array(z.string()).optional(),\n moderationClearedReason: z.string().optional(),\n moderatedAt: z.number().optional(),\n edgeSyncState: ModerationEdgeSyncStateSchema.nullable().optional(),\n edgeSyncProcessingAt: z.number().optional(),\n edgeSyncOp: ModerationEdgeSyncOpSchema.optional(),\n edgeSyncDecision: ModerationDecisionNumberSchema.optional(),\n edgeSyncAssetIds: z.array(z.string().min(1)).optional(),\n edgeSyncError: z.string().optional(),\n edgeSyncFailedAt: z.number().optional(),\n});\nexport type PublishedTelevisionEpisode = z.infer<typeof PublishedTelevisionEpisodeSchema>;\n\n// --- Hall library user preferences (per-user Hall viewing-state doc) ---\n\n// One per-user home, server-synced from day 1 (hall-viewing-experience Area 2, ruled\n// 2026-07-04): `userProfiles/{uid}/privateData/hallLibraryPreferences` (see\n// PATH_BUILDERS.hallLibraryPreferences). Writes are CALLABLE-ONLY — one core owns this\n// doc; heartbeat throttling for playback progress is client-side before the callable\n// fires. Every list on this doc is capped for launch (see HALL_LIBRARY_PREFS_CAPS) —\n// no unbounded per-user lists.\nexport const HallLibraryInProgressEntrySchema = z.object({\n itemId: z.string(),\n positionSeconds: z.number(),\n durationSeconds: z.number().optional(),\n updatedAt: z.number(),\n});\nexport type HallLibraryInProgressEntry = z.infer<typeof HallLibraryInProgressEntrySchema>;\n\nexport const HallLibraryRecentlyViewedEntrySchema = z.object({\n hallItemId: z.string(),\n itemId: z.string().optional(),\n viewedAt: z.number(),\n});\nexport type HallLibraryRecentlyViewedEntry = z.infer<typeof HallLibraryRecentlyViewedEntrySchema>;\n\nexport const HallLibrarySettingsSchema = z.object({\n tunesAutoplay: z.boolean(),\n});\nexport type HallLibrarySettings = z.infer<typeof HallLibrarySettingsSchema>;\n\nexport const HallLibraryPreferencesSchema = z.object({\n userId: z.string(),\n // Hall items the user personally hid (view filter only — see Area 6 ruling 5). Capped\n // ~200: oldest-pruned, or the hide is rejected with a friendly message once full.\n hiddenWorkIds: z.array(z.string()),\n // The \"Inked\" save-for-later watchlist (My Playbill Area 7). Capped ~200.\n inkedWorkIds: z.array(z.string()),\n // Resume position per hallItemId, LRU-capped ~50 (see HALL_LIBRARY_PREFS_CAPS.inProgress).\n // Cap enforcement is the backend core's job on write; this schema only models the shape.\n inProgress: z.record(z.string(), HallLibraryInProgressEntrySchema),\n // Server-side Keep-going/History rail source, capped ~20.\n recentlyViewed: z.array(HallLibraryRecentlyViewedEntrySchema),\n settings: HallLibrarySettingsSchema,\n lastUpdated: z.number(),\n});\nexport type HallLibraryPreferences = z.infer<typeof HallLibraryPreferencesSchema>;\n\n// --- _config singleton docs ---\n\n// Public-document page text: an intro and an intention line hold plain text, blank-line-separated\n// paragraphs. A section's video is a system slot, never a field here.\n\n/** A Future Plans heading; every plan belongs to exactly one group. */\nexport const FuturePlanGroupSchema = z.object({\n id: z.string(),\n name: z.string(),\n order: z.number(),\n intention: z.string().optional(),\n});\nexport type FuturePlanGroup = z.infer<typeof FuturePlanGroupSchema>;\n\nexport const FuturePlanItemSchema = z.object({\n id: z.string(),\n title: z.string(),\n description: z.string(),\n /** The `FuturePlanGroup.id` the plan sits under. */\n groupId: z.string(),\n /** Position within its group. */\n order: z.number(),\n});\nexport type FuturePlanItem = z.infer<typeof FuturePlanItemSchema>;\n\nexport const FuturePlansDocumentSchema = z.object({\n lastUpdated: z.number(),\n intro: z.string().optional(),\n groups: z.array(FuturePlanGroupSchema),\n plans: z.array(FuturePlanItemSchema),\n // Content version — bumped by every published release; readers treat absence as version 1.\n version: z.number().optional(),\n});\nexport type FuturePlansDocument = z.infer<typeof FuturePlansDocumentSchema>;\n\nexport const RuleGroupSchema = z.enum(RULE_GROUP_KEYS);\n\n/**\n * Who a rule or agreement point applies to: an absent type applies to every type; a set type\n * narrows it to that Work type or Hall wing only.\n */\nconst appliesToTypeFields = {\n workProjectType: z.enum(WORK_PROJECT_TYPE_KEYS).optional(),\n hallWingType: z.enum(HALL_WING_TYPE_KEYS).optional(),\n};\n\nexport const RuleSchema = z.object({\n id: z.string(),\n title: z.string(),\n description: z.string(),\n group: RuleGroupSchema,\n ...appliesToTypeFields,\n order: z.number(),\n});\nexport type Rule = z.infer<typeof RuleSchema>;\n\n/** One Artisan Agreement point; the list's order is the page order. */\nexport const AgreementPointSchema = z.object({\n id: z.string(),\n text: z.string(),\n ...appliesToTypeFields,\n});\nexport type AgreementPoint = z.infer<typeof AgreementPointSchema>;\n\nexport const ArtisanAgreementsSchema = z.object({\n intention: z.string().optional(),\n points: z.array(AgreementPointSchema),\n});\nexport type ArtisanAgreements = z.infer<typeof ArtisanAgreementsSchema>;\n\nexport const RulesAndAgreementsSchema = z.object({\n intro: z.string().optional(),\n /** Each rule group's optional intention line, shown under its heading. */\n groupIntentions: z.partialRecord(RuleGroupSchema, z.string()).optional(),\n rules: z.array(RuleSchema),\n agreements: ArtisanAgreementsSchema,\n // Content version — bumped by every published release; readers treat absence as version 1.\n version: z.number().optional(),\n // Stamped by the release publish, like every other public document's current projection.\n lastUpdated: z.number().optional(),\n});\nexport type RulesAndAgreements = z.infer<typeof RulesAndAgreementsSchema>;\n\n// --- Editable content-page docs (content-pages Firestore migration, DJ ruling 2026-07-06) ---\n//\n// /terms, /privacy, and the /take-it-down page copy render EXCLUSIVELY from\n// these `_config` singletons — no hardcoded fallbacks anywhere (banned design).\n// Seed callables create them (strict seed-if-empty: doc exists ⇒ no-op); admin\n// editors are the only writers after that, and every save bumps `version`.\n// Acceptance records (e.g. privateData.agreements.termsVersion) read `version`\n// from the DOC server-side at acceptance time — never from a constant.\n// There is NO draft flag on any content doc (DJ ruling 2026-07-06).\n\n/** One section of a long-form content page. `level` 1 = section (h2), 2 = subsection (h3). */\nexport const ContentPageSectionSchema = z.object({\n id: z.string(),\n heading: z.string(),\n level: z.union([z.literal(1), z.literal(2)]),\n /** Plain text; blank-line-separated paragraphs. */\n body: z.string(),\n order: z.number(),\n});\nexport type ContentPageSection = z.infer<typeof ContentPageSectionSchema>;\n\n/** Long-form legal page doc — the shape of BOTH `_appConfig/termsOfService` and `_appConfig/privacyPolicy`. */\nexport const LegalPageDocumentSchema = z.object({\n version: z.number(),\n lastUpdated: z.number(),\n sections: z.array(ContentPageSectionSchema),\n});\nexport type LegalPageDocument = z.infer<typeof LegalPageDocumentSchema>;\n\n/**\n * `_appConfig/takeItDownPageCopy` — the /take-it-down page's user-facing language as\n * a keyed strings map (the page is a functional form, so its copy is discrete\n * labeled strings, not long-form sections). Keys are stable identifiers defined\n * by the page (e.g. `pageTitle`, `introBody`); the admin editor renders one\n * labeled text field per key.\n */\nexport const TakeItDownPageCopySchema = z.object({\n version: z.number(),\n lastUpdated: z.number(),\n strings: z.record(z.string(), z.string()),\n});\nexport type TakeItDownPageCopy = z.infer<typeof TakeItDownPageCopySchema>;\n\n/** One labeled line of a DMCA contact block (e.g. `Email` → the agent's address). */\nexport const DmcaContactRowSchema = z.object({\n id: z.string(),\n label: z.string(),\n value: z.string(),\n order: z.number(),\n});\nexport type DmcaContactRow = z.infer<typeof DmcaContactRowSchema>;\n\n/** A titled group of contact rows (the service-provider and designated-agent blocks). */\nexport const DmcaContactBlockSchema = z.object({\n id: z.string(),\n heading: z.string(),\n order: z.number(),\n rows: z.array(DmcaContactRowSchema),\n});\nexport type DmcaContactBlock = z.infer<typeof DmcaContactBlockSchema>;\n\n/**\n * `_appConfig/dmcaPolicy` — the /dmca page's current projection: a short intro, the labeled\n * contact blocks (the designated agent's registration details), and long-form sections for the\n * notice-and-takedown process the Terms point to. Versioned and released like every other\n * public document.\n */\nexport const DmcaPolicyDocumentSchema = z.object({\n version: z.number(),\n lastUpdated: z.number(),\n intro: z.string(),\n contactBlocks: z.array(DmcaContactBlockSchema),\n sections: z.array(ContentPageSectionSchema),\n});\nexport type DmcaPolicyDocument = z.infer<typeof DmcaPolicyDocumentSchema>;\n"]}
|
|
1
|
+
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/doc-schemas/content.ts"],"names":[],"mappings":"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","sourcesContent":["// Content Firestore document SCHEMAS — Tales/Tunes/Television sub-documents, the\n// Threshold + Hall library item shapes, Hall library user preferences, and the\n// `_config` singleton docs (futurePlans, rulesAndAgreements). Types are inferred via\n// z.infer. The enum-key consts (HALL_WING_TYPE_KEYS / WORK_PROJECT_TYPE_KEYS) and the\n// UI-only filter/view types remain in ../types/content.ts.\n\nimport { z } from 'zod';\nimport { HALL_WING_TYPE_KEYS, RULE_GROUP_KEYS, WORK_PROJECT_TYPE_KEYS } from '../types/content.js';\nimport {\n ModerationDecisionNumberSchema,\n ModerationEdgeSyncOpSchema,\n ModerationEdgeSyncStateSchema,\n ModerationHiddenBySchema,\n} from './moderation.js';\nimport { MAX_THRESHOLD_PUBLISH_PARKED_REASON_LENGTH } from '../constants/business-admin.js';\nimport { FIRESTORE_INDEXED_VALUE_MAX_BYTES } from '../constants/business-platform.js';\nimport { LegalReviewNoticeReceiptSchema } from './legal-review-notice.js';\nimport {\n HALL_CONTENT_DETAIL_SURFACES,\n HALL_CONTENT_SUB_ITEM_SURFACES,\n} from '../constants/hall-content-routing.js';\n\nconst contentStatusSchema = z.enum(['unpublished', 'pending_approval', 'published']);\n\n// Per-field moderation text-clear remedy on the in-Work chapter / track / episode sub-items (the\n// published Hall projections declare the same two fields). `moderationClearedFields` lists which\n// text fields (e.g. 'title', 'description', 'content') an admin cleared to a neutral placeholder\n// and which now await steward re-entry; empty/absent when nothing was cleared. `moderationClearedReason` is the operator's reason, surfaced on the member's\n// edit surface. Extends the workProject/workRealm placeholder remedy per-field. Backend-only-writable.\nconst moderationClearedFieldsShape = {\n moderationClearedFields: z.array(z.string()).optional(),\n moderationClearedReason: z.string().optional(),\n};\n\nexport const ItemsKeySchema = z.enum(['tuneTracks', 'chapters', 'televisionEpisodes']);\nexport type ItemsKey = z.infer<typeof ItemsKeySchema>;\n\n// --- WorkProject content sub-docs ---\n\n// A Work has ONE title and ONE description, typed on the Work itself (`workingTitle` /\n// `workingDescription`); the Tale / Tune / Television section doc carries no text of its own —\n// only the covers and genres the Hall entry publishes beside the Work's text. Chapters, tracks,\n// and episodes keep their own titles and text.\n\nexport const FullTaleSchema = z.object({\n uid: z.string(),\n createdOn: z.number(),\n coverSquareAssetId: z.string().optional(),\n coverPosterAssetId: z.string().optional(),\n coverCinematicAssetId: z.string().optional(),\n workGenres: z.array(z.string()).optional(),\n});\nexport type FullTale = z.infer<typeof FullTaleSchema>;\n\nexport const FullChapterSchema = z.object({\n uid: z.string(),\n title: z.string(),\n content: z.string(),\n description: z.string(),\n order: z.number(),\n photoAssetId: z.string().optional(),\n status: contentStatusSchema,\n createdOn: z.number(),\n ...moderationClearedFieldsShape,\n moderatedAt: z.number().optional(),\n});\nexport type FullChapter = z.infer<typeof FullChapterSchema>;\n\nexport const FullTuneSchema = z.object({\n uid: z.string(),\n coverSquareAssetId: z.string().optional(),\n coverPosterAssetId: z.string().optional(),\n coverCinematicAssetId: z.string().optional(),\n workGenres: z.array(z.string()),\n createdOn: z.number(),\n});\nexport type FullTune = z.infer<typeof FullTuneSchema>;\n\nexport const FullTuneTrackSchema = z.object({\n uid: z.string(),\n title: z.string(),\n description: z.string().optional(),\n audioAssetId: z.string().optional(),\n mediaType: z.string().optional(),\n order: z.number(),\n photoAssetId: z.string().optional(),\n status: contentStatusSchema,\n createdOn: z.number(),\n ...moderationClearedFieldsShape,\n moderatedAt: z.number().optional(),\n});\nexport type FullTuneTrack = z.infer<typeof FullTuneTrackSchema>;\n\nexport const FullTelevisionSchema = z.object({\n uid: z.string(),\n createdOn: z.number(),\n coverSquareAssetId: z.string().optional(),\n coverPosterAssetId: z.string().optional(),\n coverCinematicAssetId: z.string().optional(),\n workGenres: z.array(z.string()),\n});\nexport type FullTelevision = z.infer<typeof FullTelevisionSchema>;\n\nexport const FullTelevisionEpisodeSchema = z.object({\n uid: z.string(),\n title: z.string(),\n description: z.string().optional(),\n videoAssetId: z.string(),\n mediaType: z.string().optional(),\n order: z.number(),\n photoAssetId: z.string().optional(),\n status: contentStatusSchema,\n createdOn: z.number(),\n ...moderationClearedFieldsShape,\n moderatedAt: z.number().optional(),\n});\nexport type FullTelevisionEpisode = z.infer<typeof FullTelevisionEpisodeSchema>;\n\n// --- Threshold + Hall library items ---\n\n/** `allWorkProjects/{workProjectId}/hallSubmissionReservation/reservation` — the Work's ONE\n * hall-entry reservation, created (never updated) inside the first threshold submit's\n * transaction; every later submit converges on its `hallItemId`. Backend-only. */\nexport const HallSubmissionReservationSchema = z.object({\n hallItemId: z.string().min(1),\n createdAt: z.number(),\n}).strict();\nexport type HallSubmissionReservation = z.infer<typeof HallSubmissionReservationSchema>;\n\nexport const ThresholdItemSchema = z.object({\n thresholdItemId: z.string(),\n hallItemId: z.string(),\n workProjectId: z.string(),\n workProjectType: z.enum(WORK_PROJECT_TYPE_KEYS),\n itemId: z.string(),\n itemsKey: ItemsKeySchema,\n order: z.number(),\n hallWingType: z.enum(HALL_WING_TYPE_KEYS),\n submittedAt: z.number(),\n reviewStatus: z.enum(['pending', 'needs_revision', 'approved']),\n adminNotes: z.string().optional(),\n reviewedAt: z.number().optional(),\n reviewedBy: z.string().optional(),\n // Parody / real-people AUTHOR ATTESTATION (R3, 2026-07-12). The submitting artisan\n // attests at threshold SUBMIT time that this work depicts real people (parody /\n // satire / commentary); stored with the submission and displayed READ-ONLY to the\n // reviewer. Admins never set or edit it — a reviewer who believes the flag is\n // needed and missing sends the item back needs-revision. The disclaimer shown on\n // published items is the ONE standard platform message\n // (REAL_PEOPLE_DISCLAIMER_MESSAGE) — there is no free-text disclaimer anywhere.\n hasRealPeople: z.boolean(),\n // Submission attestations — REQUIRED. The submit core refuses a submission unless the artisan\n // ticks all five, then stores each as the literal `true` with the moment they were given. A\n // threshold item without them is not a valid submission.\n attestConsistentFormat: z.literal(true),\n attestNoCredits: z.literal(true),\n attestNoBegging: z.literal(true),\n attestHumanMadeOriginal: z.literal(true),\n attestPublishStewardship: z.literal(true),\n attestedAt: z.number(),\n // The founder legal-review notice acknowledgment given with the attestations, written in the\n // same submission transaction. Present while the notice is active (the submit core refuses a\n // submission without the checkbox then); absent when the notice is off.\n legalReviewNotice: LegalReviewNoticeReceiptSchema.optional(),\n // Reviewer confirmations — stamped `true` together by the APPROVAL write and never otherwise,\n // so their presence means the item was approved with all four checks confirmed.\n confirmedNoBegging: z.literal(true).optional(),\n confirmedNoCredits: z.literal(true).optional(),\n confirmedConsistentFormat: z.literal(true).optional(),\n confirmedRealPeopleAttestation: z.literal(true).optional(),\n // Terminal publish PARK. An approved item whose publish stops without publishing (source media\n // ineligible, a blocking safety hold, a moderation hide landing after approval, an invalid work\n // type) leaves the threshold doc + admin task in place for operator intervention. The reason was\n // only ever visible in Sentry and the `system.manualIntervention` audit event; stamping it here\n // is what lets the admin review work view say WHY the item is sitting there. Optional because\n // only a park stamps it, and `reviewStatus` keeps its meaning — a park is not a new status.\n publishParkedReason: z.string().max(MAX_THRESHOLD_PUBLISH_PARKED_REASON_LENGTH).optional(),\n publishParkedAt: z.number().optional(),\n});\nexport type ThresholdItem = z.infer<typeof ThresholdItemSchema>;\n\n// --- Published change requests (launch: text-only) ---\n\n/** The published hall-content surfaces whose TEXT fields a change request (and the\n * moderation text-clear remedy) can target. Detail surfaces live on the hall parent;\n * sub-item surfaces on the published chapter/track/episode doc; the `workRealm`\n * surface targets the single `workRealms/{id}` doc (the realm grain of the one\n * text-change pipeline — R1, 2026-07-12). */\nexport const HallContentTextSurfaceSchema = z.enum([\n ...HALL_CONTENT_DETAIL_SURFACES,\n ...HALL_CONTENT_SUB_ITEM_SURFACES,\n 'workRealm',\n]);\nexport type HallContentTextSurface = z.infer<typeof HallContentTextSurfaceSchema>;\n\n/** The ONE canonical hall sub-item kind (a Tale chapter / Tune track / Television\n * episode) as carried on notification metadata and Streetz post payloads. Distinct\n * from `HallContentTextSurfaceSchema` (which keys text-change surfaces and uses the\n * compound `tuneTrack`/`televisionEpisode` identifiers). Never re-declare inline. */\nexport const HallSubItemTypeSchema = z.enum(['chapter', 'track', 'episode']);\nexport type HallSubItemType = z.infer<typeof HallSubItemTypeSchema>;\n\n/** The ONE canonical published-hall-item lifecycle status. */\nexport const PublishedHallItemStatusSchema = z.enum(['published', 'paused', 'banned']);\nexport type PublishedHallItemStatus = z.infer<typeof PublishedHallItemStatusSchema>;\n\n/** A change request's stored `targetKey`: non-empty, and short enough for its equality query to\n * be exact (an indexed value past Firestore's limit is truncated in the index). */\nexport const hallContentChangeRequestTargetKeySchema = z\n .string()\n .min(1)\n .refine((key) => new TextEncoder().encode(key).length <= FIRESTORE_INDEXED_VALUE_MAX_BYTES, {\n message: 'A change-request target key is longer than Firestore indexes exactly.',\n });\n\n// A member's proposal to change TEXT fields on a PUBLISHED hall item (Ruling 2 of the\n// admin-work-correspondence order). The live published item is NEVER unlocked and never\n// edited by the member — this doc carries the PROPOSED values only; OLD values render\n// live from the published docs. Approve = server writes the values onto the published\n// item + its live in-Work source doc; deny = nothing changes, `resolutionReason` shown\n// to the member. Writes are callable-only; reads are the owning work's active guildmates\n// + admins. `requestKind` future-proofs a media variant (new kind, no schema break).\nexport const HallContentChangeRequestSchema = z.object({\n changeRequestId: z.string(),\n requestKind: z.literal('text'),\n // One-open-per-target enforcement/query key, built only by `hallContentChangeRequestTargetKey`\n // (Hall grains) and `workRealmChangeRequestTargetKey` (realm grain).\n targetKey: hallContentChangeRequestTargetKeySchema,\n // null ⇒ the workRealm grain (no hall item involved).\n hallItemId: z.string().nullable(),\n // Always set. On the workRealm grain this is the realm's foundingWorkProjectId\n // (server-derived) so the owner list read, rules, and admin-task fields keep\n // one uniform key across all grains.\n workProjectId: z.string(),\n // null ⇒ the workRealm grain (a realm has no work-project type).\n workProjectType: z.enum(WORK_PROJECT_TYPE_KEYS).nullable(),\n surface: HallContentTextSurfaceSchema,\n // Set ⇒ the workRealm grain; null on the hall grains.\n workRealmId: z.string().nullable(),\n // null ⇒ the hall parent DETAIL (or the workRealm grain); set ⇒ a\n // chapter/track/episode sub-item.\n subItemId: z.string().nullable(),\n proposerUid: z.string(),\n // Raw doc field name → proposed new text. The top-level `surface` is the single\n // authoritative discriminator; the allowlist and each field's declaration are enforced at\n // the backend boundary by `validateHallContentTextFields` (HALL_CONTENT_TEXT_FIELDS,\n // HALL_CONTENT_CHANGE_REQUEST_INPUTS).\n proposedFields: z.record(z.string(), z.string()),\n status: z.enum(['requested', 'approved', 'denied']),\n createdAt: z.number(),\n lastUpdatedAt: z.number(),\n resolvedAt: z.number().optional(),\n resolvedBy: z.string().optional(),\n // Admin's reason, surfaced to the member (required on a deny).\n resolutionReason: z.string().optional(),\n});\nexport type HallContentChangeRequest = z.infer<typeof HallContentChangeRequestSchema>;\n\nexport const PublishedHallItemSchema = z.object({\n hallItemId: z.string(),\n workProjectId: z.string(),\n workProjectType: z.enum(WORK_PROJECT_TYPE_KEYS),\n status: PublishedHallItemStatusSchema,\n createdOn: z.number(),\n publishedAt: z.number().optional(),\n hallWingType: z.enum(HALL_WING_TYPE_KEYS),\n title: z.string().optional(),\n description: z.string().optional(),\n // REQUIRED on the published hall parent: all three covers are a publish-readiness rule, so a\n // published entry always carries every one. The working/draft section docs (FullTale / FullTune /\n // FullTelevision) keep them optional — that is where covers are uploaded one at a time.\n coverSquareAssetId: z.string().min(1),\n coverPosterAssetId: z.string().min(1),\n coverCinematicAssetId: z.string().min(1),\n workGenres: z.array(z.string()).optional(),\n followerCount: z.number().optional(),\n hidden: z.boolean(),\n // Whether the current hide was applied DIRECTly to this item or propagated by a moderation\n // CASCADE from a parent (realm/work). Absent when not hidden. Backend-only-writable.\n hiddenBy: ModerationHiddenBySchema.optional(),\n // Moderation text-clear remedy (extends the workProject/workRealm placeholder family, per-field):\n // which text fields an admin cleared to a neutral placeholder and now await steward re-entry\n // (e.g. ['title', 'description']). Empty/absent when nothing was cleared. `moderationClearedReason`\n // is the operator's reason (shown on the steward's edit surface). Backend-only-writable.\n moderationClearedFields: z.array(z.string()).optional(),\n moderationClearedReason: z.string().optional(),\n moderatedAt: z.number().optional(),\n // Parody / real-people flag (carried from the approved ThresholdItem's AUTHOR\n // attestation — R3, 2026-07-12). When true, display surfaces render the ONE\n // standard platform message (REAL_PEOPLE_DISCLAIMER_MESSAGE) prominently on the\n // published Work — never a stored free-text disclaimer. Backend-written at publish.\n hasRealPeople: z.boolean().optional(),\n});\nexport type PublishedHallItem = z.infer<typeof PublishedHallItemSchema>;\n\nexport const PublishedTuneTrackSchema = z.object({\n uid: z.string(),\n title: z.string(),\n order: z.number(),\n description: z.string().optional(),\n // REQUIRED on a published sub-item (HALL_SUB_ITEM_REQUIRED_FIELDS_BY_WORK_TYPE.Tunes): a track\n // reaches the Hall only with its audio and its picture. The working `FullTuneTrack` keeps both\n // optional — that shape has to be able to represent incomplete content.\n audioAssetId: z.string().min(1),\n photoAssetId: z.string().min(1),\n hidden: z.boolean(),\n // Direct hide vs cascade-from-parent (see PublishedHallItemSchema). Absent when not hidden.\n hiddenBy: ModerationHiddenBySchema.optional(),\n // Per-field moderation text-clear remedy (see PublishedHallItemSchema): which text fields were\n // cleared to a neutral placeholder and await steward re-entry, plus the operator's reason.\n moderationClearedFields: z.array(z.string()).optional(),\n moderationClearedReason: z.string().optional(),\n moderatedAt: z.number().optional(),\n edgeSyncState: ModerationEdgeSyncStateSchema.nullable().optional(),\n edgeSyncProcessingAt: z.number().optional(),\n edgeSyncOp: ModerationEdgeSyncOpSchema.optional(),\n edgeSyncDecision: ModerationDecisionNumberSchema.optional(),\n edgeSyncAssetIds: z.array(z.string().min(1)).optional(),\n edgeSyncError: z.string().optional(),\n edgeSyncFailedAt: z.number().optional(),\n});\nexport type PublishedTuneTrack = z.infer<typeof PublishedTuneTrackSchema>;\n\nexport const PublishedChapterSchema = z.object({\n uid: z.string(),\n title: z.string(),\n order: z.number(),\n description: z.string().optional(),\n content: z.string(),\n // REQUIRED on a published sub-item (HALL_SUB_ITEM_REQUIRED_FIELDS_BY_WORK_TYPE.Tales); the\n // working `FullChapter` keeps it optional.\n photoAssetId: z.string().min(1),\n hidden: z.boolean(),\n // Direct hide vs cascade-from-parent (see PublishedHallItemSchema). Absent when not hidden.\n hiddenBy: ModerationHiddenBySchema.optional(),\n // Per-field moderation text-clear remedy (see PublishedHallItemSchema): which text fields were\n // cleared to a neutral placeholder and await steward re-entry, plus the operator's reason.\n moderationClearedFields: z.array(z.string()).optional(),\n moderationClearedReason: z.string().optional(),\n moderatedAt: z.number().optional(),\n edgeSyncState: ModerationEdgeSyncStateSchema.nullable().optional(),\n edgeSyncProcessingAt: z.number().optional(),\n edgeSyncOp: ModerationEdgeSyncOpSchema.optional(),\n edgeSyncDecision: ModerationDecisionNumberSchema.optional(),\n edgeSyncAssetIds: z.array(z.string().min(1)).optional(),\n edgeSyncError: z.string().optional(),\n edgeSyncFailedAt: z.number().optional(),\n});\nexport type PublishedChapter = z.infer<typeof PublishedChapterSchema>;\n\nexport const PublishedTelevisionEpisodeSchema = z.object({\n uid: z.string(),\n title: z.string(),\n order: z.number(),\n description: z.string().optional(),\n // REQUIRED on a published sub-item (HALL_SUB_ITEM_REQUIRED_FIELDS_BY_WORK_TYPE.Television): an\n // episode reaches the Hall only with its video and its picture. The working\n // `FullTelevisionEpisode` keeps the picture optional.\n videoAssetId: z.string().min(1),\n photoAssetId: z.string().min(1),\n hidden: z.boolean(),\n // Direct hide vs cascade-from-parent (see PublishedHallItemSchema). Absent when not hidden.\n hiddenBy: ModerationHiddenBySchema.optional(),\n // Per-field moderation text-clear remedy (see PublishedHallItemSchema): which text fields were\n // cleared to a neutral placeholder and await steward re-entry, plus the operator's reason.\n moderationClearedFields: z.array(z.string()).optional(),\n moderationClearedReason: z.string().optional(),\n moderatedAt: z.number().optional(),\n edgeSyncState: ModerationEdgeSyncStateSchema.nullable().optional(),\n edgeSyncProcessingAt: z.number().optional(),\n edgeSyncOp: ModerationEdgeSyncOpSchema.optional(),\n edgeSyncDecision: ModerationDecisionNumberSchema.optional(),\n edgeSyncAssetIds: z.array(z.string().min(1)).optional(),\n edgeSyncError: z.string().optional(),\n edgeSyncFailedAt: z.number().optional(),\n});\nexport type PublishedTelevisionEpisode = z.infer<typeof PublishedTelevisionEpisodeSchema>;\n\n// --- Hall library user preferences (per-user Hall viewing-state doc) ---\n\n// One per-user home, server-synced from day 1 (hall-viewing-experience Area 2, ruled\n// 2026-07-04): `userProfiles/{uid}/privateData/hallLibraryPreferences` (see\n// PATH_BUILDERS.hallLibraryPreferences). Writes are CALLABLE-ONLY — one core owns this\n// doc; heartbeat throttling for playback progress is client-side before the callable\n// fires. Every list on this doc is capped for launch (see HALL_LIBRARY_PREFS_CAPS) —\n// no unbounded per-user lists.\nexport const HallLibraryInProgressEntrySchema = z.object({\n itemId: z.string(),\n positionSeconds: z.number(),\n durationSeconds: z.number().optional(),\n updatedAt: z.number(),\n});\nexport type HallLibraryInProgressEntry = z.infer<typeof HallLibraryInProgressEntrySchema>;\n\nexport const HallLibraryRecentlyViewedEntrySchema = z.object({\n hallItemId: z.string(),\n itemId: z.string().optional(),\n viewedAt: z.number(),\n});\nexport type HallLibraryRecentlyViewedEntry = z.infer<typeof HallLibraryRecentlyViewedEntrySchema>;\n\nexport const HallLibrarySettingsSchema = z.object({\n tunesAutoplay: z.boolean(),\n});\nexport type HallLibrarySettings = z.infer<typeof HallLibrarySettingsSchema>;\n\nexport const HallLibraryPreferencesSchema = z.object({\n userId: z.string(),\n // Hall items the user personally hid (view filter only — see Area 6 ruling 5). Capped\n // ~200: oldest-pruned, or the hide is rejected with a friendly message once full.\n hiddenWorkIds: z.array(z.string()),\n // The \"Inked\" save-for-later watchlist (My Playbill Area 7). Capped ~200.\n inkedWorkIds: z.array(z.string()),\n // Resume position per hallItemId, LRU-capped ~50 (see HALL_LIBRARY_PREFS_CAPS.inProgress).\n // Cap enforcement is the backend core's job on write; this schema only models the shape.\n inProgress: z.record(z.string(), HallLibraryInProgressEntrySchema),\n // Server-side Keep-going/History rail source, capped ~20.\n recentlyViewed: z.array(HallLibraryRecentlyViewedEntrySchema),\n settings: HallLibrarySettingsSchema,\n lastUpdated: z.number(),\n});\nexport type HallLibraryPreferences = z.infer<typeof HallLibraryPreferencesSchema>;\n\n// --- _config singleton docs ---\n\n// Public-document page text: an intro and an intention line hold plain text, blank-line-separated\n// paragraphs. A section's video is a system slot, never a field here.\n\n/** A Future Plans heading; every plan belongs to exactly one group. */\nexport const FuturePlanGroupSchema = z.object({\n id: z.string(),\n name: z.string(),\n order: z.number(),\n intention: z.string().optional(),\n});\nexport type FuturePlanGroup = z.infer<typeof FuturePlanGroupSchema>;\n\nexport const FuturePlanItemSchema = z.object({\n id: z.string(),\n title: z.string(),\n description: z.string(),\n /** The `FuturePlanGroup.id` the plan sits under. */\n groupId: z.string(),\n /** Position within its group. */\n order: z.number(),\n});\nexport type FuturePlanItem = z.infer<typeof FuturePlanItemSchema>;\n\nexport const FuturePlansDocumentSchema = z.object({\n lastUpdated: z.number(),\n intro: z.string().optional(),\n groups: z.array(FuturePlanGroupSchema),\n plans: z.array(FuturePlanItemSchema),\n // Content version — bumped by every published release; readers treat absence as version 1.\n version: z.number().optional(),\n});\nexport type FuturePlansDocument = z.infer<typeof FuturePlansDocumentSchema>;\n\nexport const RuleGroupSchema = z.enum(RULE_GROUP_KEYS);\n\n/**\n * Who a rule or agreement point applies to: an absent type applies to every type; a set type\n * narrows it to that Work type or Hall wing only.\n */\nconst appliesToTypeFields = {\n workProjectType: z.enum(WORK_PROJECT_TYPE_KEYS).optional(),\n hallWingType: z.enum(HALL_WING_TYPE_KEYS).optional(),\n};\n\nexport const RuleSchema = z.object({\n id: z.string(),\n title: z.string(),\n description: z.string(),\n group: RuleGroupSchema,\n ...appliesToTypeFields,\n order: z.number(),\n});\nexport type Rule = z.infer<typeof RuleSchema>;\n\n/** One Artisan Agreement point; the list's order is the page order. */\nexport const AgreementPointSchema = z.object({\n id: z.string(),\n text: z.string(),\n ...appliesToTypeFields,\n});\nexport type AgreementPoint = z.infer<typeof AgreementPointSchema>;\n\nexport const ArtisanAgreementsSchema = z.object({\n intention: z.string().optional(),\n points: z.array(AgreementPointSchema),\n});\nexport type ArtisanAgreements = z.infer<typeof ArtisanAgreementsSchema>;\n\nexport const RulesAndAgreementsSchema = z.object({\n intro: z.string().optional(),\n /** Each rule group's optional intention line, shown under its heading. */\n groupIntentions: z.partialRecord(RuleGroupSchema, z.string()).optional(),\n rules: z.array(RuleSchema),\n agreements: ArtisanAgreementsSchema,\n // Content version — bumped by every published release; readers treat absence as version 1.\n version: z.number().optional(),\n // Stamped by the release publish, like every other public document's current projection.\n lastUpdated: z.number().optional(),\n});\nexport type RulesAndAgreements = z.infer<typeof RulesAndAgreementsSchema>;\n\n// --- Editable content-page docs (content-pages Firestore migration, DJ ruling 2026-07-06) ---\n//\n// /terms, /privacy, and the /take-it-down page copy render EXCLUSIVELY from\n// these `_config` singletons — no hardcoded fallbacks anywhere (banned design).\n// Seed callables create them (strict seed-if-empty: doc exists ⇒ no-op); admin\n// editors are the only writers after that, and every save bumps `version`.\n// Acceptance records (e.g. privateData.agreements.termsVersion) read `version`\n// from the DOC server-side at acceptance time — never from a constant.\n// There is NO draft flag on any content doc (DJ ruling 2026-07-06).\n\n/** One section of a long-form content page. `level` 1 = section (h2), 2 = subsection (h3). */\nexport const ContentPageSectionSchema = z.object({\n id: z.string(),\n heading: z.string(),\n level: z.union([z.literal(1), z.literal(2)]),\n /** Plain text; blank-line-separated paragraphs. */\n body: z.string(),\n order: z.number(),\n});\nexport type ContentPageSection = z.infer<typeof ContentPageSectionSchema>;\n\n/** Long-form legal page doc — the shape of BOTH `_appConfig/termsOfService` and `_appConfig/privacyPolicy`. */\nexport const LegalPageDocumentSchema = z.object({\n version: z.number(),\n lastUpdated: z.number(),\n sections: z.array(ContentPageSectionSchema),\n});\nexport type LegalPageDocument = z.infer<typeof LegalPageDocumentSchema>;\n\n/**\n * `_appConfig/takeItDownPageCopy` — the /take-it-down page's user-facing language as\n * a keyed strings map (the page is a functional form, so its copy is discrete\n * labeled strings, not long-form sections). Keys are stable identifiers defined\n * by the page (e.g. `pageTitle`, `introBody`); the admin editor renders one\n * labeled text field per key.\n */\nexport const TakeItDownPageCopySchema = z.object({\n version: z.number(),\n lastUpdated: z.number(),\n strings: z.record(z.string(), z.string()),\n});\nexport type TakeItDownPageCopy = z.infer<typeof TakeItDownPageCopySchema>;\n\n/** One labeled line of a DMCA contact block (e.g. `Email` → the agent's address). */\nexport const DmcaContactRowSchema = z.object({\n id: z.string(),\n label: z.string(),\n value: z.string(),\n order: z.number(),\n});\nexport type DmcaContactRow = z.infer<typeof DmcaContactRowSchema>;\n\n/** A titled group of contact rows (the service-provider and designated-agent blocks). */\nexport const DmcaContactBlockSchema = z.object({\n id: z.string(),\n heading: z.string(),\n order: z.number(),\n rows: z.array(DmcaContactRowSchema),\n});\nexport type DmcaContactBlock = z.infer<typeof DmcaContactBlockSchema>;\n\n/**\n * `_appConfig/dmcaPolicy` — the /dmca page's current projection: a short intro, the labeled\n * contact blocks (the designated agent's registration details), and long-form sections for the\n * notice-and-takedown process the Terms point to. Versioned and released like every other\n * public document.\n */\nexport const DmcaPolicyDocumentSchema = z.object({\n version: z.number(),\n lastUpdated: z.number(),\n intro: z.string(),\n contactBlocks: z.array(DmcaContactBlockSchema),\n sections: z.array(ContentPageSectionSchema),\n});\nexport type DmcaPolicyDocument = z.infer<typeof DmcaPolicyDocumentSchema>;\n"]}
|
|
@@ -1052,6 +1052,7 @@ export declare const COLLECTION_SCHEMAS: {
|
|
|
1052
1052
|
attestNoCredits: z.ZodLiteral<true>;
|
|
1053
1053
|
attestNoBegging: z.ZodLiteral<true>;
|
|
1054
1054
|
attestHumanMadeOriginal: z.ZodLiteral<true>;
|
|
1055
|
+
attestPublishStewardship: z.ZodLiteral<true>;
|
|
1055
1056
|
attestedAt: z.ZodNumber;
|
|
1056
1057
|
legalReviewNotice: z.ZodOptional<z.ZodObject<{
|
|
1057
1058
|
revision: z.ZodString;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/registry.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiN7B,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/registry.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiN7B,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqQkB,CAAC;AAElD,MAAM,MAAM,wBAAwB,GAAG,MAAM,OAAO,kBAAkB,CAAC;AAEvE;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;CAmBiC,CAAC;AAEvE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAOvC,CAAC"}
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import type { FileOrigin } from './file-origin.js';
|
|
2
2
|
export declare const fileOriginRowLabel: Record<FileOrigin, string>;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
3
|
+
/** How long an upload row's time reads as relative ("5m ago") before it reads as a clock time. */
|
|
4
|
+
export declare const UPLOAD_ROW_RELATIVE_TIME_CUTOFF_MS: number;
|
|
5
|
+
/** An upload row's words for its time and its file's kind. */
|
|
6
|
+
export declare const UPLOAD_ROW_DISPLAY_COPY: {
|
|
7
|
+
readonly justNow: "just now";
|
|
8
|
+
readonly minutesAgo: (minutes: number) => string;
|
|
9
|
+
readonly hoursAgo: (hours: number) => string;
|
|
10
|
+
readonly yesterdayAt: (time: string) => string;
|
|
11
|
+
readonly dateAt: (date: string, time: string) => string;
|
|
12
|
+
readonly fileType: {
|
|
13
|
+
readonly image: "Image";
|
|
14
|
+
readonly video: "Video";
|
|
15
|
+
readonly audio: "Audio";
|
|
16
|
+
readonly other: "File";
|
|
17
|
+
};
|
|
18
|
+
};
|
|
15
19
|
//# sourceMappingURL=upload-tray-display.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload-tray-display.d.ts","sourceRoot":"","sources":["../../src/media/upload-tray-display.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"upload-tray-display.d.ts","sourceRoot":"","sources":["../../src/media/upload-tray-display.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AASnD,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAyBzD,CAAC;AAQF,kGAAkG;AAClG,eAAO,MAAM,kCAAkC,QAAqB,CAAC;AAErE,8DAA8D;AAC9D,eAAO,MAAM,uBAAuB;;mCAEZ,MAAM;+BACV,MAAM;iCACJ,MAAM;4BACX,MAAM,QAAQ,MAAM;;;;;;;CAE3B,CAAC"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { getSimplifiedMediaType } from '@ttt-productions/media-schemas';
|
|
2
1
|
// =============================================================================
|
|
3
2
|
// User-facing labels per fileOrigin
|
|
4
3
|
// =============================================================================
|
|
@@ -32,77 +31,19 @@ export const fileOriginRowLabel = {
|
|
|
32
31
|
'ncii-evidence': 'Take-it-down evidence',
|
|
33
32
|
};
|
|
34
33
|
// =============================================================================
|
|
35
|
-
//
|
|
34
|
+
// Row time and file kind
|
|
36
35
|
// =============================================================================
|
|
37
36
|
//
|
|
38
|
-
//
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
*/
|
|
51
|
-
export function formatUploadTimestamp(createdAtMs, nowMs, cutoffMs = DEFAULT_RELATIVE_TIME_CUTOFF_MS) {
|
|
52
|
-
const diffMs = Math.max(0, nowMs - createdAtMs);
|
|
53
|
-
if (diffMs < cutoffMs) {
|
|
54
|
-
// Relative path.
|
|
55
|
-
if (diffMs < 60_000)
|
|
56
|
-
return 'just now';
|
|
57
|
-
const minutes = Math.floor(diffMs / 60_000);
|
|
58
|
-
if (minutes < 60)
|
|
59
|
-
return `${minutes}m ago`;
|
|
60
|
-
const hours = Math.floor(diffMs / 3_600_000);
|
|
61
|
-
return `${hours}h ago`;
|
|
62
|
-
}
|
|
63
|
-
// Absolute path.
|
|
64
|
-
const created = new Date(createdAtMs);
|
|
65
|
-
const now = new Date(nowMs);
|
|
66
|
-
const timeStr = created.toLocaleTimeString(undefined, {
|
|
67
|
-
hour: 'numeric',
|
|
68
|
-
minute: '2-digit',
|
|
69
|
-
});
|
|
70
|
-
const sameDay = created.getFullYear() === now.getFullYear() &&
|
|
71
|
-
created.getMonth() === now.getMonth() &&
|
|
72
|
-
created.getDate() === now.getDate();
|
|
73
|
-
if (sameDay)
|
|
74
|
-
return timeStr;
|
|
75
|
-
const yesterday = new Date(nowMs - 24 * 60 * 60 * 1000);
|
|
76
|
-
const isYesterday = created.getFullYear() === yesterday.getFullYear() &&
|
|
77
|
-
created.getMonth() === yesterday.getMonth() &&
|
|
78
|
-
created.getDate() === yesterday.getDate();
|
|
79
|
-
if (isYesterday)
|
|
80
|
-
return `Yesterday ${timeStr}`;
|
|
81
|
-
const dateStr = created.toLocaleDateString(undefined, {
|
|
82
|
-
month: 'short',
|
|
83
|
-
day: 'numeric',
|
|
84
|
-
});
|
|
85
|
-
return `${dateStr}, ${timeStr}`;
|
|
86
|
-
}
|
|
87
|
-
// =============================================================================
|
|
88
|
-
// File type labeling
|
|
89
|
-
// =============================================================================
|
|
90
|
-
//
|
|
91
|
-
// Friendly label for a content type string. Wraps getSimplifiedMediaType
|
|
92
|
-
// from media-schemas with capitalization for tray display.
|
|
93
|
-
// Returns null when contentType is undefined/empty.
|
|
94
|
-
export function getFileTypeLabel(contentType) {
|
|
95
|
-
if (!contentType)
|
|
96
|
-
return null;
|
|
97
|
-
switch (getSimplifiedMediaType(contentType)) {
|
|
98
|
-
case 'image':
|
|
99
|
-
return 'Image';
|
|
100
|
-
case 'video':
|
|
101
|
-
return 'Video';
|
|
102
|
-
case 'audio':
|
|
103
|
-
return 'Audio';
|
|
104
|
-
default:
|
|
105
|
-
return 'File';
|
|
106
|
-
}
|
|
107
|
-
}
|
|
37
|
+
// The words and cutoff the app hands upload-ui's `createUploadDisplayFormatters`.
|
|
38
|
+
/** How long an upload row's time reads as relative ("5m ago") before it reads as a clock time. */
|
|
39
|
+
export const UPLOAD_ROW_RELATIVE_TIME_CUTOFF_MS = 6 * 60 * 60 * 1000;
|
|
40
|
+
/** An upload row's words for its time and its file's kind. */
|
|
41
|
+
export const UPLOAD_ROW_DISPLAY_COPY = {
|
|
42
|
+
justNow: 'just now',
|
|
43
|
+
minutesAgo: (minutes) => `${minutes}m ago`,
|
|
44
|
+
hoursAgo: (hours) => `${hours}h ago`,
|
|
45
|
+
yesterdayAt: (time) => `Yesterday ${time}`,
|
|
46
|
+
dateAt: (date, time) => `${date}, ${time}`,
|
|
47
|
+
fileType: { image: 'Image', video: 'Video', audio: 'Audio', other: 'File' },
|
|
48
|
+
};
|
|
108
49
|
//# sourceMappingURL=upload-tray-display.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload-tray-display.js","sourceRoot":"","sources":["../../src/media/upload-tray-display.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"upload-tray-display.js","sourceRoot":"","sources":["../../src/media/upload-tray-display.ts"],"names":[],"mappings":"AAEA,gFAAgF;AAChF,oCAAoC;AACpC,gFAAgF;AAChF,EAAE;AACF,yEAAyE;AACzE,mEAAmE;AAEnE,MAAM,CAAC,MAAM,kBAAkB,GAA+B;IAC5D,iBAAiB,EAAE,iBAAiB;IACpC,mBAAmB,EAAE,OAAO;IAC5B,eAAe,EAAE,aAAa;IAC9B,oBAAoB,EAAE,oBAAoB;IAC1C,qBAAqB,EAAE,qBAAqB;IAC5C,iBAAiB,EAAE,UAAU;IAC7B,gFAAgF;IAChF,iFAAiF;IACjF,6DAA6D;IAC7D,uBAAuB,EAAE,gBAAgB;IACzC,gBAAgB,EAAE,gBAAgB;IAClC,0BAA0B,EAAE,YAAY;IACxC,0BAA0B,EAAE,YAAY;IACxC,6BAA6B,EAAE,YAAY;IAC3C,aAAa,EAAE,aAAa;IAC5B,eAAe,EAAE,eAAe;IAChC,kBAAkB,EAAE,aAAa;IACjC,kBAAkB,EAAE,aAAa;IACjC,0BAA0B,EAAE,eAAe;IAC3C,0BAA0B,EAAE,eAAe;IAC3C,YAAY,EAAE,YAAY;IAC1B,mBAAmB,EAAE,mBAAmB;IACxC,gBAAgB,EAAE,cAAc;IAChC,eAAe,EAAE,uBAAuB;CACzC,CAAC;AAEF,gFAAgF;AAChF,yBAAyB;AACzB,gFAAgF;AAChF,EAAE;AACF,kFAAkF;AAElF,kGAAkG;AAClG,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAErE,8DAA8D;AAC9D,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,OAAO,EAAE,UAAU;IACnB,UAAU,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,GAAG,OAAO,OAAO;IAClD,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,GAAG,KAAK,OAAO;IAC5C,WAAW,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,aAAa,IAAI,EAAE;IAClD,MAAM,EAAE,CAAC,IAAY,EAAE,IAAY,EAAE,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,EAAE;IAC1D,QAAQ,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE;CACnE,CAAC","sourcesContent":["import type { FileOrigin } from './file-origin.js';\n\n// =============================================================================\n// User-facing labels per fileOrigin\n// =============================================================================\n//\n// Generic labels for upload tray rows. Same regardless of platform (web,\n// iOS, Android, smart TV) since they describe TTT domain entities.\n\nexport const fileOriginRowLabel: Record<FileOrigin, string> = {\n 'profile-picture': 'Profile picture',\n 'craft-skill-media': 'Craft',\n 'squareStreetz': 'Square post',\n 'commission-posting': 'Commission posting',\n 'commission-proposal': 'Commission proposal',\n 'audition-prompt': 'Audition',\n // Neutral on purpose: this origin creates BOTH Platform and Sponsored auditions\n // (AdminAuditionPromptTargetInfoSchema.type), so it cannot borrow either settled\n // AUDITION_TYPES label without lying about half its uploads.\n 'admin-audition-prompt': 'Admin audition',\n 'audition-entry': 'Audition entry',\n 'hallLibrary-cover-square': 'Work cover',\n 'hallLibrary-cover-poster': 'Work cover',\n 'hallLibrary-cover-cinematic': 'Work cover',\n 'realm-cover': 'Realm cover',\n 'chapter-photo': 'Chapter photo',\n 'tune-track-photo': 'Track photo',\n 'tune-track-audio': 'Track audio',\n 'television-episode-photo': 'Episode photo',\n 'television-episode-video': 'Episode video',\n 'work-asset': 'Work asset',\n 'conversation-file': 'Conversation file',\n 'system-content': 'System video',\n 'ncii-evidence': 'Take-it-down evidence',\n};\n\n// =============================================================================\n// Row time and file kind\n// =============================================================================\n//\n// The words and cutoff the app hands upload-ui's `createUploadDisplayFormatters`.\n\n/** How long an upload row's time reads as relative (\"5m ago\") before it reads as a clock time. */\nexport const UPLOAD_ROW_RELATIVE_TIME_CUTOFF_MS = 6 * 60 * 60 * 1000;\n\n/** An upload row's words for its time and its file's kind. */\nexport const UPLOAD_ROW_DISPLAY_COPY = {\n justNow: 'just now',\n minutesAgo: (minutes: number) => `${minutes}m ago`,\n hoursAgo: (hours: number) => `${hours}h ago`,\n yesterdayAt: (time: string) => `Yesterday ${time}`,\n dateAt: (date: string, time: string) => `${date}, ${time}`,\n fileType: { image: 'Image', video: 'Video', audio: 'Audio', other: 'File' },\n} as const;\n"]}
|
|
@@ -1,6 +1,109 @@
|
|
|
1
1
|
import { HALL_CONTENT_TEXT_FIELDS } from '../constants/business-content.js';
|
|
2
2
|
import type { WorkProjectType } from '../types/content.js';
|
|
3
|
-
import type
|
|
3
|
+
import { type FullChapter, type FullTelevisionEpisode, type FullTuneTrack } from '../doc-schemas/content.js';
|
|
4
|
+
/**
|
|
5
|
+
* Each work type's published Hall sub-item: the subcollection it is stored in and the schema it is
|
|
6
|
+
* stored as, declared together. A writer looks its work type up once and takes both from the one
|
|
7
|
+
* entry, so one kind's shape can never be stored in another kind's subcollection.
|
|
8
|
+
*/
|
|
9
|
+
export declare const PUBLISHED_HALL_SUB_ITEM_BY_WORK_TYPE: {
|
|
10
|
+
readonly Tales: {
|
|
11
|
+
readonly subcollection: import("../paths/collections.js").HallItemSubcollection;
|
|
12
|
+
readonly schema: import("zod").ZodObject<{
|
|
13
|
+
uid: import("zod").ZodString;
|
|
14
|
+
title: import("zod").ZodString;
|
|
15
|
+
order: import("zod").ZodNumber;
|
|
16
|
+
description: import("zod").ZodOptional<import("zod").ZodString>;
|
|
17
|
+
content: import("zod").ZodString;
|
|
18
|
+
photoAssetId: import("zod").ZodString;
|
|
19
|
+
hidden: import("zod").ZodBoolean;
|
|
20
|
+
hiddenBy: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
21
|
+
direct: "direct";
|
|
22
|
+
cascade: "cascade";
|
|
23
|
+
}>>;
|
|
24
|
+
moderationClearedFields: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
|
|
25
|
+
moderationClearedReason: import("zod").ZodOptional<import("zod").ZodString>;
|
|
26
|
+
moderatedAt: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
27
|
+
edgeSyncState: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodEnum<{
|
|
28
|
+
failed: "failed";
|
|
29
|
+
processing: "processing";
|
|
30
|
+
}>>>;
|
|
31
|
+
edgeSyncProcessingAt: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
32
|
+
edgeSyncOp: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
33
|
+
block: "block";
|
|
34
|
+
blockClear: "blockClear";
|
|
35
|
+
}>>;
|
|
36
|
+
edgeSyncDecision: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
37
|
+
edgeSyncAssetIds: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
|
|
38
|
+
edgeSyncError: import("zod").ZodOptional<import("zod").ZodString>;
|
|
39
|
+
edgeSyncFailedAt: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
40
|
+
}, import("zod/v4/core").$strip>;
|
|
41
|
+
};
|
|
42
|
+
readonly Tunes: {
|
|
43
|
+
readonly subcollection: import("../paths/collections.js").HallItemSubcollection;
|
|
44
|
+
readonly schema: import("zod").ZodObject<{
|
|
45
|
+
uid: import("zod").ZodString;
|
|
46
|
+
title: import("zod").ZodString;
|
|
47
|
+
order: import("zod").ZodNumber;
|
|
48
|
+
description: import("zod").ZodOptional<import("zod").ZodString>;
|
|
49
|
+
audioAssetId: import("zod").ZodString;
|
|
50
|
+
photoAssetId: import("zod").ZodString;
|
|
51
|
+
hidden: import("zod").ZodBoolean;
|
|
52
|
+
hiddenBy: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
53
|
+
direct: "direct";
|
|
54
|
+
cascade: "cascade";
|
|
55
|
+
}>>;
|
|
56
|
+
moderationClearedFields: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
|
|
57
|
+
moderationClearedReason: import("zod").ZodOptional<import("zod").ZodString>;
|
|
58
|
+
moderatedAt: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
59
|
+
edgeSyncState: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodEnum<{
|
|
60
|
+
failed: "failed";
|
|
61
|
+
processing: "processing";
|
|
62
|
+
}>>>;
|
|
63
|
+
edgeSyncProcessingAt: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
64
|
+
edgeSyncOp: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
65
|
+
block: "block";
|
|
66
|
+
blockClear: "blockClear";
|
|
67
|
+
}>>;
|
|
68
|
+
edgeSyncDecision: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
69
|
+
edgeSyncAssetIds: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
|
|
70
|
+
edgeSyncError: import("zod").ZodOptional<import("zod").ZodString>;
|
|
71
|
+
edgeSyncFailedAt: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
72
|
+
}, import("zod/v4/core").$strip>;
|
|
73
|
+
};
|
|
74
|
+
readonly Television: {
|
|
75
|
+
readonly subcollection: import("../paths/collections.js").HallItemSubcollection;
|
|
76
|
+
readonly schema: import("zod").ZodObject<{
|
|
77
|
+
uid: import("zod").ZodString;
|
|
78
|
+
title: import("zod").ZodString;
|
|
79
|
+
order: import("zod").ZodNumber;
|
|
80
|
+
description: import("zod").ZodOptional<import("zod").ZodString>;
|
|
81
|
+
videoAssetId: import("zod").ZodString;
|
|
82
|
+
photoAssetId: import("zod").ZodString;
|
|
83
|
+
hidden: import("zod").ZodBoolean;
|
|
84
|
+
hiddenBy: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
85
|
+
direct: "direct";
|
|
86
|
+
cascade: "cascade";
|
|
87
|
+
}>>;
|
|
88
|
+
moderationClearedFields: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
|
|
89
|
+
moderationClearedReason: import("zod").ZodOptional<import("zod").ZodString>;
|
|
90
|
+
moderatedAt: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
91
|
+
edgeSyncState: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodEnum<{
|
|
92
|
+
failed: "failed";
|
|
93
|
+
processing: "processing";
|
|
94
|
+
}>>>;
|
|
95
|
+
edgeSyncProcessingAt: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
96
|
+
edgeSyncOp: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
97
|
+
block: "block";
|
|
98
|
+
blockClear: "blockClear";
|
|
99
|
+
}>>;
|
|
100
|
+
edgeSyncDecision: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
101
|
+
edgeSyncAssetIds: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
|
|
102
|
+
edgeSyncError: import("zod").ZodOptional<import("zod").ZodString>;
|
|
103
|
+
edgeSyncFailedAt: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
104
|
+
}, import("zod/v4/core").$strip>;
|
|
105
|
+
};
|
|
106
|
+
};
|
|
4
107
|
/** A published hall-content surface whose text a change request or the moderation
|
|
5
108
|
* text-clear remedy can target. */
|
|
6
109
|
export type HallContentTextFieldSurface = keyof typeof HALL_CONTENT_TEXT_FIELDS;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hall-content.d.ts","sourceRoot":"","sources":["../../src/utils/hall-content.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,wBAAwB,EAGzB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"hall-content.d.ts","sourceRoot":"","sources":["../../src/utils/hall-content.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,wBAAwB,EAGzB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EACnB,MAAM,2BAA2B,CAAC;AAGnC;;;;GAIG;AACH,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAIuC,CAAC;AAEzF;oCACoC;AACpC,MAAM,MAAM,2BAA2B,GAAG,MAAM,OAAO,wBAAwB,CAAC;AAEhF,0FAA0F;AAC1F,MAAM,MAAM,wBAAwB,CAAC,CAAC,SAAS,2BAA2B,IACxE,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,wBAAwB,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAExE,MAAM,MAAM,+BAA+B,CAAC,CAAC,SAAS,2BAA2B,IAC7E;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC,CAAC,CAAA;CAAE,GACnE;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD;;;;;;;;;;;;GAYG;AACH,wBAAgB,6BAA6B,CAAC,CAAC,SAAS,2BAA2B,EACjF,OAAO,EAAE,CAAC,EACV,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAChD,+BAA+B,CAAC,CAAC,CAAC,CAkBpC;AAED;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAC1C,eAAe,EAAE,eAAe,EAChC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACzC,MAAM,EAAE,CAQV;AAED,4EAA4E;AAC5E,wBAAgB,wBAAwB,CACtC,eAAe,EAAE,eAAe,EAChC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACzC,OAAO,CAET;AAED,+FAA+F;AAC/F,MAAM,MAAM,iBAAiB,GAAG,CAAC,WAAW,GAAG,aAAa,GAAG,qBAAqB,CAAC,CAAC,QAAQ,CAAC,CAAC;AAEhG;;uBAEuB;AACvB,eAAO,MAAM,6BAA6B,4CAAoF,CAAC;AAE/H;kBACkB;AAClB,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAE5D;AAED;0CAC0C;AAC1C,wBAAgB,iCAAiC,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAEvG;AAED;aACa;AACb,wBAAgB,+BAA+B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3E"}
|
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
// Pure hall-content rules shared by the member surfaces and the backend cores that own the
|
|
2
|
-
// writes. Server-safe: constants and plain functions only.
|
|
2
|
+
// writes. Server-safe: constants, canonical schemas, and plain functions only.
|
|
3
3
|
import { checkTextField } from './text-field.js';
|
|
4
4
|
import { HALL_CONTENT_TEXT_FIELDS, HALL_SUB_ITEM_REQUIRED_FIELDS_BY_WORK_TYPE, HALL_SUB_ITEM_REQUIREMENT_LABELS, } from '../constants/business-content.js';
|
|
5
5
|
import { HALL_CONTENT_CHANGE_REQUEST_INPUTS } from '../constants/text-fields.js';
|
|
6
|
+
import { PublishedChapterSchema, PublishedTelevisionEpisodeSchema, PublishedTuneTrackSchema, } from '../doc-schemas/content.js';
|
|
7
|
+
import { HALL_ITEM_SUBCOLLECTION_BY_WORK_TYPE } from '../paths/collections.js';
|
|
8
|
+
/**
|
|
9
|
+
* Each work type's published Hall sub-item: the subcollection it is stored in and the schema it is
|
|
10
|
+
* stored as, declared together. A writer looks its work type up once and takes both from the one
|
|
11
|
+
* entry, so one kind's shape can never be stored in another kind's subcollection.
|
|
12
|
+
*/
|
|
13
|
+
export const PUBLISHED_HALL_SUB_ITEM_BY_WORK_TYPE = {
|
|
14
|
+
Tales: { subcollection: HALL_ITEM_SUBCOLLECTION_BY_WORK_TYPE.Tales, schema: PublishedChapterSchema },
|
|
15
|
+
Tunes: { subcollection: HALL_ITEM_SUBCOLLECTION_BY_WORK_TYPE.Tunes, schema: PublishedTuneTrackSchema },
|
|
16
|
+
Television: { subcollection: HALL_ITEM_SUBCOLLECTION_BY_WORK_TYPE.Television, schema: PublishedTelevisionEpisodeSchema },
|
|
17
|
+
};
|
|
6
18
|
/**
|
|
7
19
|
* The ONE strict per-surface check for a proposed hall-content text map: every key must be a
|
|
8
20
|
* field that surface owns, and every value must meet that field's change-request declaration
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hall-content.js","sourceRoot":"","sources":["../../src/utils/hall-content.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F
|
|
1
|
+
{"version":3,"file":"hall-content.js","sourceRoot":"","sources":["../../src/utils/hall-content.ts"],"names":[],"mappings":"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","sourcesContent":["// Pure hall-content rules shared by the member surfaces and the backend cores that own the\n// writes. Server-safe: constants, canonical schemas, and plain functions only.\n\nimport { checkTextField, type TextFieldDeclaration } from './text-field.js';\nimport {\n HALL_CONTENT_TEXT_FIELDS,\n HALL_SUB_ITEM_REQUIRED_FIELDS_BY_WORK_TYPE,\n HALL_SUB_ITEM_REQUIREMENT_LABELS,\n} from '../constants/business-content.js';\nimport { HALL_CONTENT_CHANGE_REQUEST_INPUTS } from '../constants/text-fields.js';\nimport type { WorkProjectType } from '../types/content.js';\nimport {\n PublishedChapterSchema,\n PublishedTelevisionEpisodeSchema,\n PublishedTuneTrackSchema,\n type FullChapter,\n type FullTelevisionEpisode,\n type FullTuneTrack,\n} from '../doc-schemas/content.js';\nimport { HALL_ITEM_SUBCOLLECTION_BY_WORK_TYPE } from '../paths/collections.js';\n\n/**\n * Each work type's published Hall sub-item: the subcollection it is stored in and the schema it is\n * stored as, declared together. A writer looks its work type up once and takes both from the one\n * entry, so one kind's shape can never be stored in another kind's subcollection.\n */\nexport const PUBLISHED_HALL_SUB_ITEM_BY_WORK_TYPE = {\n Tales: { subcollection: HALL_ITEM_SUBCOLLECTION_BY_WORK_TYPE.Tales, schema: PublishedChapterSchema },\n Tunes: { subcollection: HALL_ITEM_SUBCOLLECTION_BY_WORK_TYPE.Tunes, schema: PublishedTuneTrackSchema },\n Television: { subcollection: HALL_ITEM_SUBCOLLECTION_BY_WORK_TYPE.Television, schema: PublishedTelevisionEpisodeSchema },\n} as const satisfies Record<WorkProjectType, { subcollection: string; schema: unknown }>;\n\n/** A published hall-content surface whose text a change request or the moderation\n * text-clear remedy can target. */\nexport type HallContentTextFieldSurface = keyof typeof HALL_CONTENT_TEXT_FIELDS;\n\n/** The proposed-text map a given surface accepts: only that surface's own field names. */\nexport type HallContentTextFieldsFor<S extends HallContentTextFieldSurface> =\n Partial<Record<(typeof HALL_CONTENT_TEXT_FIELDS)[S][number], string>>;\n\nexport type HallContentTextFieldsValidation<S extends HallContentTextFieldSurface> =\n | { readonly ok: true; readonly fields: HallContentTextFieldsFor<S> }\n | { readonly ok: false; readonly reason: string };\n\n/**\n * The ONE strict per-surface check for a proposed hall-content text map: every key must be a\n * field that surface owns, and every value must meet that field's change-request declaration\n * (`HALL_CONTENT_CHANGE_REQUEST_INPUTS` — trimmed, never empty, within its max, in its format). The\n * stored `hallContentChangeRequests` shape is a flat field map with the request's own `surface`\n * as the single authoritative discriminator, so this is where the allowlist is enforced — at the\n * backend boundary, before the map is persisted or written onto a published doc.\n *\n * The allowlist comes from the canonical Hall text-field map and each rule from the field's\n * declaration; there is no second allowlist anywhere.\n *\n * @returns the normalized (trimmed) field map, or the user-facing reason it was rejected.\n */\nexport function validateHallContentTextFields<S extends HallContentTextFieldSurface>(\n surface: S,\n proposedFields: Readonly<Record<string, unknown>>,\n): HallContentTextFieldsValidation<S> {\n const allowed = HALL_CONTENT_TEXT_FIELDS[surface] as readonly string[];\n const normalized: Record<string, string> = {};\n\n for (const [field, rawValue] of Object.entries(proposedFields)) {\n if (!allowed.includes(field)) {\n return { ok: false, reason: `Field \"${field}\" is not editable on this item.` };\n }\n const declaration = (HALL_CONTENT_CHANGE_REQUEST_INPUTS[surface] as Record<string, TextFieldDeclaration>)[field];\n const result = checkTextField(declaration, typeof rawValue === 'string' ? rawValue : '');\n if (!result.ok) return { ok: false, reason: result.reason };\n normalized[field] = result.value;\n }\n\n if (Object.keys(normalized).length === 0) {\n return { ok: false, reason: 'No valid text fields proposed.' };\n }\n return { ok: true, fields: normalized as HallContentTextFieldsFor<S> };\n}\n\n/**\n * The requirements a Tale chapter / Tune track / Television episode has not met yet, as the\n * wording a surface can show, in the canonical field order. Empty means the sub-item may be\n * submitted, approved, and published.\n *\n * ONE owner for the member-side eligibility filter and all three backend cores — none of them\n * restates the per-type branch.\n */\nexport function unmetHallSubItemRequirements(\n workProjectType: WorkProjectType,\n subItem: Readonly<Record<string, unknown>>,\n): string[] {\n const required = HALL_SUB_ITEM_REQUIRED_FIELDS_BY_WORK_TYPE[workProjectType];\n return required\n .filter((field) => {\n const value = subItem[field];\n return typeof value !== 'string' || value.trim().length === 0;\n })\n .map((field) => HALL_SUB_ITEM_REQUIREMENT_LABELS[field]);\n}\n\n/** True when the sub-item meets every requirement its work type imposes. */\nexport function isHallSubItemPublishable(\n workProjectType: WorkProjectType,\n subItem: Readonly<Record<string, unknown>>,\n): boolean {\n return unmetHallSubItemRequirements(workProjectType, subItem).length === 0;\n}\n\n/** The review status every chapter / track / episode carries (one set for the three kinds). */\nexport type HallSubItemStatus = (FullChapter | FullTuneTrack | FullTelevisionEpisode)['status'];\n\n/** The statuses that lock a sub-item against edits and media attaches: submitted for library\n * review, or published to the Hall. Text changes to a published item go through a change\n * request instead. */\nexport const HALL_SUB_ITEM_LOCKED_STATUSES = ['pending_approval', 'published'] as const satisfies readonly HallSubItemStatus[];\n\n/** True when a sub-item in this status is locked; any other value, a missing status included, is\n * not a lock. */\nexport function isHallSubItemLocked(status: unknown): boolean {\n return (HALL_SUB_ITEM_LOCKED_STATUSES as readonly unknown[]).includes(status);\n}\n\n/** The `targetKey` a Hall-grain change request is stored and queried under: one open request per\n * Hall item's detail or per sub-item. */\nexport function hallContentChangeRequestTargetKey(hallItemId: string, subItemId?: string | null): string {\n return `${hallItemId}_${subItemId ?? 'detail'}`;\n}\n\n/** The `targetKey` a Realm-grain change request is stored and queried under: one open request per\n * Realm. */\nexport function workRealmChangeRequestTargetKey(workRealmId: string): string {\n return `realm_${workRealmId}`;\n}\n"]}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export * from './admin-standing.js';
|
|
2
2
|
export * from './age-derivation.js';
|
|
3
3
|
export * from './app-config.js';
|
|
4
|
-
export * from './format.js';
|
|
5
4
|
export * from './guild-chat-access.js';
|
|
6
5
|
export * from './guild-invite-system-message.js';
|
|
7
6
|
export * from './hall-content.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kCAAkC,CAAC;AACjD,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC"}
|
package/dist/utils/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export * from './admin-standing.js';
|
|
2
2
|
export * from './age-derivation.js';
|
|
3
3
|
export * from './app-config.js';
|
|
4
|
-
export * from './format.js';
|
|
5
4
|
export * from './guild-chat-access.js';
|
|
6
5
|
export * from './guild-invite-system-message.js';
|
|
7
6
|
export * from './hall-content.js';
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kCAAkC,CAAC;AACjD,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC","sourcesContent":["export * from './admin-standing.js';\nexport * from './age-derivation.js';\nexport * from './app-config.js';\nexport * from './guild-chat-access.js';\nexport * from './guild-invite-system-message.js';\nexport * from './hall-content.js';\nexport * from './password.js';\nexport * from './text-field.js';\nexport * from './public-documents.js';\nexport * from './pledge-totals.js';\nexport * from './pledge-refund-eligibility.js';\nexport * from './work-file-folder.js';\nexport * from './work-realm-eligibility.js';\nexport * from './work-realm-name.js';\nexport * from './display-name-reservation.js';\nexport * from './work-publish-readiness.js';\n"]}
|
package/package.json
CHANGED
package/dist/utils/format.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Format a byte count as a human-readable string: "24 KB", "1.2 MB", "850 B".
|
|
3
|
-
* Returns null when bytes is undefined / non-finite / negative.
|
|
4
|
-
*/
|
|
5
|
-
export declare function formatFileSize(bytes: number | undefined): string | null;
|
|
6
|
-
//# sourceMappingURL=format.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/utils/format.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAUvE"}
|
package/dist/utils/format.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Format a byte count as a human-readable string: "24 KB", "1.2 MB", "850 B".
|
|
3
|
-
* Returns null when bytes is undefined / non-finite / negative.
|
|
4
|
-
*/
|
|
5
|
-
export function formatFileSize(bytes) {
|
|
6
|
-
if (bytes === undefined || !Number.isFinite(bytes) || bytes < 0)
|
|
7
|
-
return null;
|
|
8
|
-
if (bytes < 1024)
|
|
9
|
-
return `${bytes} B`;
|
|
10
|
-
if (bytes < 1024 * 1024)
|
|
11
|
-
return `${Math.round(bytes / 1024)} KB`;
|
|
12
|
-
if (bytes < 1024 * 1024 * 1024) {
|
|
13
|
-
const mb = bytes / (1024 * 1024);
|
|
14
|
-
return `${mb < 10 ? mb.toFixed(1) : Math.round(mb)} MB`;
|
|
15
|
-
}
|
|
16
|
-
const gb = bytes / (1024 * 1024 * 1024);
|
|
17
|
-
return `${gb < 10 ? gb.toFixed(1) : Math.round(gb)} GB`;
|
|
18
|
-
}
|
|
19
|
-
//# sourceMappingURL=format.js.map
|
package/dist/utils/format.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/utils/format.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAyB;IACtD,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7E,IAAI,KAAK,GAAG,IAAI;QAAE,OAAO,GAAG,KAAK,IAAI,CAAC;IACtC,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IACjE,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;QAC/B,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QACjC,OAAO,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC;IAC1D,CAAC;IACD,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;IACxC,OAAO,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC;AAC1D,CAAC","sourcesContent":["/**\n * Format a byte count as a human-readable string: \"24 KB\", \"1.2 MB\", \"850 B\".\n * Returns null when bytes is undefined / non-finite / negative.\n */\nexport function formatFileSize(bytes: number | undefined): string | null {\n if (bytes === undefined || !Number.isFinite(bytes) || bytes < 0) return null;\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;\n if (bytes < 1024 * 1024 * 1024) {\n const mb = bytes / (1024 * 1024);\n return `${mb < 10 ? mb.toFixed(1) : Math.round(mb)} MB`;\n }\n const gb = bytes / (1024 * 1024 * 1024);\n return `${gb < 10 ? gb.toFixed(1) : Math.round(gb)} GB`;\n}\n"]}
|