@updraft-solutions/mcrit-sdk 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-TDONQRKU.cjs → chunk-IDEPTVFF.cjs} +116 -8
- package/dist/{chunk-QG44Y5LO.js → chunk-ZKXYKICY.js} +115 -7
- package/dist/index.cjs +10 -6
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +14 -10
- package/dist/sanitize/index.cjs +53 -0
- package/dist/sanitize/index.d.cts +50 -0
- package/dist/sanitize/index.d.ts +50 -0
- package/dist/sanitize/index.js +53 -0
- package/dist/schemas/index.cjs +6 -2
- package/dist/schemas/index.d.cts +15 -15
- package/dist/schemas/index.d.ts +15 -15
- package/dist/schemas/index.js +5 -1
- package/dist/{training-BibD4HsC.d.cts → training-DRuphnSP.d.cts} +34669 -23276
- package/dist/{training-BibD4HsC.d.ts → training-DRuphnSP.d.ts} +34669 -23276
- package/dist/types/index.d.cts +19 -2
- package/dist/types/index.d.ts +19 -2
- package/package.json +12 -1
- package/src/sanitize/index.ts +92 -0
- package/src/schemas/models.ts +134 -6
- package/src/types/ai.ts +1 -0
- package/src/types/models.ts +17 -0
package/dist/types/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { aB as activitySchema, aC as addressSchema, aD as aircraftPositionSchema, aE as aircraftRatingSchema, aJ as airplaneSchema, aI as airplanePermissionSchema, aK as airplaneShareInviteSchema, aL as airportSchema, aM as alertSchema, aN as allowedDocumentTypeSchema, aO as approachTypeSchema, aP as availSchema, aQ as baseMembershipSchema,
|
|
2
|
+
import { aB as activitySchema, aC as addressSchema, aD as aircraftPositionSchema, aE as aircraftRatingSchema, aJ as airplaneSchema, aI as airplanePermissionSchema, aK as airplaneShareInviteSchema, aL as airportSchema, aM as alertSchema, aN as allowedDocumentTypeSchema, aO as approachTypeSchema, aP as availSchema, aQ as baseMembershipSchema, aS as bookingSchema, aU as commentSchema, aV as companySchema, a$ as courseSchema, aZ as courseEnrollmentSchema, a_ as courseFeeSchema, aG as airplaneIssueSeverityEnum, b5 as documentSchema, b1 as documentComplianceStatus, b2 as documentRequirement, b3 as documentRequirementGroup, b4 as documentRequirementGroupAssignment, b6 as documentShareSchema, b7 as documentType, b9 as eventSchema, bb as expenseSchema, ba as expenseItemSchema, bc as extendedAirplaneSchema, be as feeSchema, bd as feeCategoryOptionsSchema, bf as flightLogSchema, bm as invoiceSchema, bo as landingSchema, bn as landingFeeSchema, bq as maintenanceEventSchema, bp as maintenanceEventEstimationSchema, br as maintenanceStatusSchema, bs as mediaCollection, bu as membershipSchema, bv as membershipSignupSchema, bw as postSchema, by as prePaidPackageSchema, bz as priceSchema, bA as qualificationSchema, bB as recurringFlightSchema, bC as roleSchema, bD as runwaySchema, bE as scheduledFlightSchema, bF as settingSchema, bG as specialFlightSchema, bN as tagSchema, bO as ticketSchema, bY as userSchema, bW as userAircraftRatingSchema, bX as userQualificationSchema, bZ as waypointSchema, aF as airplaneIssueSchema, aH as airplaneIssueStatusEnum, B as BaseModel$1, aX as courseCheckSyllabusSchema, aY as courseEnrollmentMetricsSchema, bt as mediaSchema, l as FormSubmission } from '../training-DRuphnSP.cjs';
|
|
3
3
|
|
|
4
4
|
type BaseModel = z.infer<typeof BaseModel$1>;
|
|
5
5
|
type User = z.infer<typeof userSchema>;
|
|
@@ -61,17 +61,33 @@ type AirplaneIssueStatus = z.infer<typeof airplaneIssueStatusEnum>;
|
|
|
61
61
|
type Event = z.infer<typeof eventSchema>;
|
|
62
62
|
type Ticket = z.infer<typeof ticketSchema>;
|
|
63
63
|
type Post = z.infer<typeof postSchema>;
|
|
64
|
+
/**
|
|
65
|
+
* Full-replacement tag sync entry — `id` marks an existing tag (wins over
|
|
66
|
+
* name matching), fresh tags carry only name (+ optional color) and are
|
|
67
|
+
* created server-side on save.
|
|
68
|
+
*/
|
|
69
|
+
interface TagSyncEntry {
|
|
70
|
+
id?: number | null;
|
|
71
|
+
name: string;
|
|
72
|
+
color?: string | null;
|
|
73
|
+
}
|
|
64
74
|
interface CreatePostInput {
|
|
65
75
|
title?: string | null;
|
|
66
76
|
content: string;
|
|
67
77
|
sticky?: boolean;
|
|
68
78
|
public?: boolean;
|
|
79
|
+
comments_disabled?: boolean;
|
|
80
|
+
tags?: TagSyncEntry[];
|
|
81
|
+
/** Action flag, not persisted: notify company members on publish. */
|
|
82
|
+
notify?: boolean;
|
|
69
83
|
}
|
|
70
84
|
interface UpdatePostInput {
|
|
71
85
|
title?: string | null;
|
|
72
86
|
content: string;
|
|
73
87
|
sticky?: boolean;
|
|
74
88
|
public?: boolean;
|
|
89
|
+
comments_disabled?: boolean;
|
|
90
|
+
tags?: TagSyncEntry[];
|
|
75
91
|
}
|
|
76
92
|
interface CreateAirplaneIssueInput {
|
|
77
93
|
title?: string | null;
|
|
@@ -277,6 +293,7 @@ interface LogbookFlightLogPayload {
|
|
|
277
293
|
role: string;
|
|
278
294
|
}[];
|
|
279
295
|
membership_id: number | null;
|
|
296
|
+
billing_profile_id?: number | null;
|
|
280
297
|
}
|
|
281
298
|
interface LogbookSuggestionMeta {
|
|
282
299
|
flags?: string[];
|
|
@@ -419,4 +436,4 @@ interface LandingFeeInvoiceApplyResult {
|
|
|
419
436
|
issues: string[];
|
|
420
437
|
}
|
|
421
438
|
|
|
422
|
-
export type { Activity, Address, AiSuggestedMilestone, AiSuggestion, AiSuggestionStatus, AircraftBlock, AircraftBlockReason, AircraftPosition, AircraftRating, Airplane, AirplaneIssue, AirplaneIssueSeverity, AirplaneIssueStatus, AirplanePermission, AirplaneShareInvite, Airport, Alert, AllowedDocumentType, ApiResponse, ApproachType, Avail, BackgroundTask, BackgroundTaskStatus, BaseMembership, BaseModel, Booking, Comment, Company, ComplianceData, ComplianceGroup, ComplianceGroupSource, ComplianceRequirement, ComplianceRequirementGroup, ComplianceResponse, ComplianceSummary, Course, CourseCheckSyllabus, CourseDescriptionSuggestionPayload, CourseEnrollment, CourseEnrollmentMetrics, CourseFee, CreateAirplaneIssueInput, CreateCommentInput, CreatePostInput, DataWrappedResponse, DeferAirplaneIssueInput, DiscardedRow, Document, DocumentComplianceStatus, DocumentRequirement, DocumentRequirementGroup, DocumentRequirementGroupAssignment, DocumentShare, DocumentType, Event, Expense, ExpenseItem, ExtendedAirplane, Fee, FeeCategoryOptions, FlightLog, GroupedPermissions, Invoice, Landing, LandingFee, LandingFeeImportResult, LandingFeeInvoiceApplyPayload, LandingFeeInvoiceApplyResult, LandingFeeInvoicePreview, LandingFeeInvoicePreviewRow, LandingFeeTemplateParams, LogbookFlightLogPayload, LogbookStageResult, LogbookSuggestion, LogbookSuggestionMeta, MaintenanceEvent, MaintenanceEventEstimation, MaintenanceStatus, Media, MediaCollection, Membership, MembershipSignup, PaginatedResponse, PermissionItem, Post, PrePaidPackage, Price, Qualification, RecurringFlight, ResolveAirplaneIssueInput, Resource, Role, RoleDetail, RoleListItem, Runway, ScheduledFlight, Setting, SpecialFlight, Tag, Ticket, ToggleFavoriteResponse, UpdateAirplaneIssueInput, UpdateCommentInput, UpdatePostInput, User, UserAircraftRating, UserQualification, Waypoint };
|
|
439
|
+
export type { Activity, Address, AiSuggestedMilestone, AiSuggestion, AiSuggestionStatus, AircraftBlock, AircraftBlockReason, AircraftPosition, AircraftRating, Airplane, AirplaneIssue, AirplaneIssueSeverity, AirplaneIssueStatus, AirplanePermission, AirplaneShareInvite, Airport, Alert, AllowedDocumentType, ApiResponse, ApproachType, Avail, BackgroundTask, BackgroundTaskStatus, BaseMembership, BaseModel, Booking, Comment, Company, ComplianceData, ComplianceGroup, ComplianceGroupSource, ComplianceRequirement, ComplianceRequirementGroup, ComplianceResponse, ComplianceSummary, Course, CourseCheckSyllabus, CourseDescriptionSuggestionPayload, CourseEnrollment, CourseEnrollmentMetrics, CourseFee, CreateAirplaneIssueInput, CreateCommentInput, CreatePostInput, DataWrappedResponse, DeferAirplaneIssueInput, DiscardedRow, Document, DocumentComplianceStatus, DocumentRequirement, DocumentRequirementGroup, DocumentRequirementGroupAssignment, DocumentShare, DocumentType, Event, Expense, ExpenseItem, ExtendedAirplane, Fee, FeeCategoryOptions, FlightLog, GroupedPermissions, Invoice, Landing, LandingFee, LandingFeeImportResult, LandingFeeInvoiceApplyPayload, LandingFeeInvoiceApplyResult, LandingFeeInvoicePreview, LandingFeeInvoicePreviewRow, LandingFeeTemplateParams, LogbookFlightLogPayload, LogbookStageResult, LogbookSuggestion, LogbookSuggestionMeta, MaintenanceEvent, MaintenanceEventEstimation, MaintenanceStatus, Media, MediaCollection, Membership, MembershipSignup, PaginatedResponse, PermissionItem, Post, PrePaidPackage, Price, Qualification, RecurringFlight, ResolveAirplaneIssueInput, Resource, Role, RoleDetail, RoleListItem, Runway, ScheduledFlight, Setting, SpecialFlight, Tag, TagSyncEntry, Ticket, ToggleFavoriteResponse, UpdateAirplaneIssueInput, UpdateCommentInput, UpdatePostInput, User, UserAircraftRating, UserQualification, Waypoint };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { aB as activitySchema, aC as addressSchema, aD as aircraftPositionSchema, aE as aircraftRatingSchema, aJ as airplaneSchema, aI as airplanePermissionSchema, aK as airplaneShareInviteSchema, aL as airportSchema, aM as alertSchema, aN as allowedDocumentTypeSchema, aO as approachTypeSchema, aP as availSchema, aQ as baseMembershipSchema,
|
|
2
|
+
import { aB as activitySchema, aC as addressSchema, aD as aircraftPositionSchema, aE as aircraftRatingSchema, aJ as airplaneSchema, aI as airplanePermissionSchema, aK as airplaneShareInviteSchema, aL as airportSchema, aM as alertSchema, aN as allowedDocumentTypeSchema, aO as approachTypeSchema, aP as availSchema, aQ as baseMembershipSchema, aS as bookingSchema, aU as commentSchema, aV as companySchema, a$ as courseSchema, aZ as courseEnrollmentSchema, a_ as courseFeeSchema, aG as airplaneIssueSeverityEnum, b5 as documentSchema, b1 as documentComplianceStatus, b2 as documentRequirement, b3 as documentRequirementGroup, b4 as documentRequirementGroupAssignment, b6 as documentShareSchema, b7 as documentType, b9 as eventSchema, bb as expenseSchema, ba as expenseItemSchema, bc as extendedAirplaneSchema, be as feeSchema, bd as feeCategoryOptionsSchema, bf as flightLogSchema, bm as invoiceSchema, bo as landingSchema, bn as landingFeeSchema, bq as maintenanceEventSchema, bp as maintenanceEventEstimationSchema, br as maintenanceStatusSchema, bs as mediaCollection, bu as membershipSchema, bv as membershipSignupSchema, bw as postSchema, by as prePaidPackageSchema, bz as priceSchema, bA as qualificationSchema, bB as recurringFlightSchema, bC as roleSchema, bD as runwaySchema, bE as scheduledFlightSchema, bF as settingSchema, bG as specialFlightSchema, bN as tagSchema, bO as ticketSchema, bY as userSchema, bW as userAircraftRatingSchema, bX as userQualificationSchema, bZ as waypointSchema, aF as airplaneIssueSchema, aH as airplaneIssueStatusEnum, B as BaseModel$1, aX as courseCheckSyllabusSchema, aY as courseEnrollmentMetricsSchema, bt as mediaSchema, l as FormSubmission } from '../training-DRuphnSP.js';
|
|
3
3
|
|
|
4
4
|
type BaseModel = z.infer<typeof BaseModel$1>;
|
|
5
5
|
type User = z.infer<typeof userSchema>;
|
|
@@ -61,17 +61,33 @@ type AirplaneIssueStatus = z.infer<typeof airplaneIssueStatusEnum>;
|
|
|
61
61
|
type Event = z.infer<typeof eventSchema>;
|
|
62
62
|
type Ticket = z.infer<typeof ticketSchema>;
|
|
63
63
|
type Post = z.infer<typeof postSchema>;
|
|
64
|
+
/**
|
|
65
|
+
* Full-replacement tag sync entry — `id` marks an existing tag (wins over
|
|
66
|
+
* name matching), fresh tags carry only name (+ optional color) and are
|
|
67
|
+
* created server-side on save.
|
|
68
|
+
*/
|
|
69
|
+
interface TagSyncEntry {
|
|
70
|
+
id?: number | null;
|
|
71
|
+
name: string;
|
|
72
|
+
color?: string | null;
|
|
73
|
+
}
|
|
64
74
|
interface CreatePostInput {
|
|
65
75
|
title?: string | null;
|
|
66
76
|
content: string;
|
|
67
77
|
sticky?: boolean;
|
|
68
78
|
public?: boolean;
|
|
79
|
+
comments_disabled?: boolean;
|
|
80
|
+
tags?: TagSyncEntry[];
|
|
81
|
+
/** Action flag, not persisted: notify company members on publish. */
|
|
82
|
+
notify?: boolean;
|
|
69
83
|
}
|
|
70
84
|
interface UpdatePostInput {
|
|
71
85
|
title?: string | null;
|
|
72
86
|
content: string;
|
|
73
87
|
sticky?: boolean;
|
|
74
88
|
public?: boolean;
|
|
89
|
+
comments_disabled?: boolean;
|
|
90
|
+
tags?: TagSyncEntry[];
|
|
75
91
|
}
|
|
76
92
|
interface CreateAirplaneIssueInput {
|
|
77
93
|
title?: string | null;
|
|
@@ -277,6 +293,7 @@ interface LogbookFlightLogPayload {
|
|
|
277
293
|
role: string;
|
|
278
294
|
}[];
|
|
279
295
|
membership_id: number | null;
|
|
296
|
+
billing_profile_id?: number | null;
|
|
280
297
|
}
|
|
281
298
|
interface LogbookSuggestionMeta {
|
|
282
299
|
flags?: string[];
|
|
@@ -419,4 +436,4 @@ interface LandingFeeInvoiceApplyResult {
|
|
|
419
436
|
issues: string[];
|
|
420
437
|
}
|
|
421
438
|
|
|
422
|
-
export type { Activity, Address, AiSuggestedMilestone, AiSuggestion, AiSuggestionStatus, AircraftBlock, AircraftBlockReason, AircraftPosition, AircraftRating, Airplane, AirplaneIssue, AirplaneIssueSeverity, AirplaneIssueStatus, AirplanePermission, AirplaneShareInvite, Airport, Alert, AllowedDocumentType, ApiResponse, ApproachType, Avail, BackgroundTask, BackgroundTaskStatus, BaseMembership, BaseModel, Booking, Comment, Company, ComplianceData, ComplianceGroup, ComplianceGroupSource, ComplianceRequirement, ComplianceRequirementGroup, ComplianceResponse, ComplianceSummary, Course, CourseCheckSyllabus, CourseDescriptionSuggestionPayload, CourseEnrollment, CourseEnrollmentMetrics, CourseFee, CreateAirplaneIssueInput, CreateCommentInput, CreatePostInput, DataWrappedResponse, DeferAirplaneIssueInput, DiscardedRow, Document, DocumentComplianceStatus, DocumentRequirement, DocumentRequirementGroup, DocumentRequirementGroupAssignment, DocumentShare, DocumentType, Event, Expense, ExpenseItem, ExtendedAirplane, Fee, FeeCategoryOptions, FlightLog, GroupedPermissions, Invoice, Landing, LandingFee, LandingFeeImportResult, LandingFeeInvoiceApplyPayload, LandingFeeInvoiceApplyResult, LandingFeeInvoicePreview, LandingFeeInvoicePreviewRow, LandingFeeTemplateParams, LogbookFlightLogPayload, LogbookStageResult, LogbookSuggestion, LogbookSuggestionMeta, MaintenanceEvent, MaintenanceEventEstimation, MaintenanceStatus, Media, MediaCollection, Membership, MembershipSignup, PaginatedResponse, PermissionItem, Post, PrePaidPackage, Price, Qualification, RecurringFlight, ResolveAirplaneIssueInput, Resource, Role, RoleDetail, RoleListItem, Runway, ScheduledFlight, Setting, SpecialFlight, Tag, Ticket, ToggleFavoriteResponse, UpdateAirplaneIssueInput, UpdateCommentInput, UpdatePostInput, User, UserAircraftRating, UserQualification, Waypoint };
|
|
439
|
+
export type { Activity, Address, AiSuggestedMilestone, AiSuggestion, AiSuggestionStatus, AircraftBlock, AircraftBlockReason, AircraftPosition, AircraftRating, Airplane, AirplaneIssue, AirplaneIssueSeverity, AirplaneIssueStatus, AirplanePermission, AirplaneShareInvite, Airport, Alert, AllowedDocumentType, ApiResponse, ApproachType, Avail, BackgroundTask, BackgroundTaskStatus, BaseMembership, BaseModel, Booking, Comment, Company, ComplianceData, ComplianceGroup, ComplianceGroupSource, ComplianceRequirement, ComplianceRequirementGroup, ComplianceResponse, ComplianceSummary, Course, CourseCheckSyllabus, CourseDescriptionSuggestionPayload, CourseEnrollment, CourseEnrollmentMetrics, CourseFee, CreateAirplaneIssueInput, CreateCommentInput, CreatePostInput, DataWrappedResponse, DeferAirplaneIssueInput, DiscardedRow, Document, DocumentComplianceStatus, DocumentRequirement, DocumentRequirementGroup, DocumentRequirementGroupAssignment, DocumentShare, DocumentType, Event, Expense, ExpenseItem, ExtendedAirplane, Fee, FeeCategoryOptions, FlightLog, GroupedPermissions, Invoice, Landing, LandingFee, LandingFeeImportResult, LandingFeeInvoiceApplyPayload, LandingFeeInvoiceApplyResult, LandingFeeInvoicePreview, LandingFeeInvoicePreviewRow, LandingFeeTemplateParams, LogbookFlightLogPayload, LogbookStageResult, LogbookSuggestion, LogbookSuggestionMeta, MaintenanceEvent, MaintenanceEventEstimation, MaintenanceStatus, Media, MediaCollection, Membership, MembershipSignup, PaginatedResponse, PermissionItem, Post, PrePaidPackage, Price, Qualification, RecurringFlight, ResolveAirplaneIssueInput, Resource, Role, RoleDetail, RoleListItem, Runway, ScheduledFlight, Setting, SpecialFlight, Tag, TagSyncEntry, Ticket, ToggleFavoriteResponse, UpdateAirplaneIssueInput, UpdateCommentInput, UpdatePostInput, User, UserAircraftRating, UserQualification, Waypoint };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@updraft-solutions/mcrit-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Shared TypeScript types, Zod schemas, and pure helpers for the MCRIT aviation fleet management platform",
|
|
5
5
|
"homepage": "https://github.com/updraft-solutions/mcrit-sdk#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -126,6 +126,17 @@
|
|
|
126
126
|
"types": "./dist/pagination/index.d.cts",
|
|
127
127
|
"default": "./dist/pagination/index.cjs"
|
|
128
128
|
}
|
|
129
|
+
},
|
|
130
|
+
"./sanitize": {
|
|
131
|
+
"source": "./src/sanitize/index.ts",
|
|
132
|
+
"import": {
|
|
133
|
+
"types": "./dist/sanitize/index.d.ts",
|
|
134
|
+
"default": "./dist/sanitize/index.js"
|
|
135
|
+
},
|
|
136
|
+
"require": {
|
|
137
|
+
"types": "./dist/sanitize/index.d.cts",
|
|
138
|
+
"default": "./dist/sanitize/index.cjs"
|
|
139
|
+
}
|
|
129
140
|
}
|
|
130
141
|
},
|
|
131
142
|
"files": [
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared HTML-sanitizing policy for TipTap rich text (posts, knowledge
|
|
3
|
+
* articles, …). The allow-lists live HERE so the app that writes content
|
|
4
|
+
* (mcrit-app) and the surfaces that render it (homepage, future clients)
|
|
5
|
+
* can never drift apart — a drift would mean content is sanitized
|
|
6
|
+
* differently where it's written versus where it's publicly shown.
|
|
7
|
+
*
|
|
8
|
+
* The SDK deliberately has no DOMPurify dependency: consumers pass their
|
|
9
|
+
* own instance to {@link createHtmlSanitizers} (browser DOMPurify,
|
|
10
|
+
* isomorphic-dompurify on SSR, …).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** Structural subset of DOMPurify we rely on — keeps it a peer concern. */
|
|
14
|
+
export interface HtmlPurifier {
|
|
15
|
+
sanitize(html: string, config?: Record<string, unknown>): string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Rich text from the TipTap post editor: common formatting, headings,
|
|
20
|
+
* links, lists, quotes and code.
|
|
21
|
+
*/
|
|
22
|
+
export const richTextSanitizeConfig = {
|
|
23
|
+
ALLOWED_TAGS: [
|
|
24
|
+
"p",
|
|
25
|
+
"br",
|
|
26
|
+
"strong",
|
|
27
|
+
"em",
|
|
28
|
+
"u",
|
|
29
|
+
"s",
|
|
30
|
+
"a",
|
|
31
|
+
"h1",
|
|
32
|
+
"h2",
|
|
33
|
+
"h3",
|
|
34
|
+
"h4",
|
|
35
|
+
"h5",
|
|
36
|
+
"h6",
|
|
37
|
+
"ul",
|
|
38
|
+
"ol",
|
|
39
|
+
"li",
|
|
40
|
+
"blockquote",
|
|
41
|
+
"code",
|
|
42
|
+
"pre",
|
|
43
|
+
],
|
|
44
|
+
ALLOWED_ATTR: ["href", "target", "rel", "class", "style"],
|
|
45
|
+
ALLOW_DATA_ATTR: false,
|
|
46
|
+
} as const;
|
|
47
|
+
|
|
48
|
+
/** Minimal inline formatting — simple comments and basic text fields. */
|
|
49
|
+
export const basicTextSanitizeConfig = {
|
|
50
|
+
ALLOWED_TAGS: ["br", "a", "strong", "em", "code", "p"],
|
|
51
|
+
ALLOWED_ATTR: ["href", "target", "rel", "class"],
|
|
52
|
+
ALLOW_DATA_ATTR: false,
|
|
53
|
+
} as const;
|
|
54
|
+
|
|
55
|
+
/** Everything stripped — plain-text snippets and previews. */
|
|
56
|
+
export const stripSanitizeConfig = {
|
|
57
|
+
ALLOWED_TAGS: [],
|
|
58
|
+
ALLOWED_ATTR: [],
|
|
59
|
+
} as const;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Bind the shared policies to a DOMPurify(-compatible) instance.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* import DOMPurify from "dompurify";
|
|
66
|
+
* const { sanitizeRichText, stripHtml } = createHtmlSanitizers(DOMPurify);
|
|
67
|
+
*/
|
|
68
|
+
export function createHtmlSanitizers(purifier: HtmlPurifier) {
|
|
69
|
+
const sanitize = (
|
|
70
|
+
html: string | null | undefined,
|
|
71
|
+
config?: Record<string, unknown>,
|
|
72
|
+
): string => {
|
|
73
|
+
if (!html) {
|
|
74
|
+
return "";
|
|
75
|
+
}
|
|
76
|
+
return purifier.sanitize(html, config);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const sanitizeRichText = (html: string | null | undefined): string =>
|
|
80
|
+
sanitize(html, richTextSanitizeConfig as unknown as Record<string, unknown>);
|
|
81
|
+
|
|
82
|
+
const sanitizeBasicText = (html: string | null | undefined): string =>
|
|
83
|
+
sanitize(html, basicTextSanitizeConfig as unknown as Record<string, unknown>);
|
|
84
|
+
|
|
85
|
+
/** Strip all HTML to whitespace-normalized plain text. */
|
|
86
|
+
const stripHtml = (html: string | null | undefined): string =>
|
|
87
|
+
sanitize(html, stripSanitizeConfig as unknown as Record<string, unknown>)
|
|
88
|
+
.replace(/\s+/g, " ")
|
|
89
|
+
.trim();
|
|
90
|
+
|
|
91
|
+
return { sanitize, sanitizeRichText, sanitizeBasicText, stripHtml };
|
|
92
|
+
}
|
package/src/schemas/models.ts
CHANGED
|
@@ -735,6 +735,47 @@ export const allowedDocumentTypeSchema = z.object({
|
|
|
735
735
|
.optional(),
|
|
736
736
|
});
|
|
737
737
|
|
|
738
|
+
// Billing recipient (formerly "Address"; the `addresses` table was renamed
|
|
739
|
+
// to `billing_profiles` — see BillingProfileResource.php). A membership/user
|
|
740
|
+
// can own several profiles (e.g. private vs. "Firma"); invoices, flight logs
|
|
741
|
+
// and expense items each point at one via `billing_profile_id`.
|
|
742
|
+
export const billingProfileSchema = z.object({
|
|
743
|
+
// BillingProfileResource never actually emits a `type` key today; kept
|
|
744
|
+
// optional for forward-compat / discriminated-union consistency with
|
|
745
|
+
// sibling schemas in this file.
|
|
746
|
+
type: z.literal("billing_profile").optional(),
|
|
747
|
+
id: z.number(),
|
|
748
|
+
owner_type: z.string(),
|
|
749
|
+
owner_id: z.number(),
|
|
750
|
+
label: z.string().nullable(),
|
|
751
|
+
is_default: z.boolean(),
|
|
752
|
+
name: z.string().nullable(),
|
|
753
|
+
company: z.string().nullable(),
|
|
754
|
+
address_street_1: z.string().nullable(),
|
|
755
|
+
address_street_2: z.string().nullable(),
|
|
756
|
+
city: z.string().nullable(),
|
|
757
|
+
state: z.string().nullable(),
|
|
758
|
+
zip: z.string().nullable(),
|
|
759
|
+
phone: z.string().nullable(),
|
|
760
|
+
fax: z.string().nullable(),
|
|
761
|
+
iso_country: z.string().nullable(),
|
|
762
|
+
vat_id: z.string().nullable(),
|
|
763
|
+
email: z.string().nullable(),
|
|
764
|
+
archived_at: z.string().nullable(),
|
|
765
|
+
source_billing_profile_id: z.number().nullable(),
|
|
766
|
+
is_synced: z.boolean(),
|
|
767
|
+
frozen_at: z.string().nullable(),
|
|
768
|
+
// Present only when the profile is frozen (frozen_by_user_id !== null).
|
|
769
|
+
frozen_by: z
|
|
770
|
+
.object({
|
|
771
|
+
id: z.number(),
|
|
772
|
+
name: z.string().nullable().optional(),
|
|
773
|
+
})
|
|
774
|
+
.optional(),
|
|
775
|
+
created_at: z.string(),
|
|
776
|
+
updated_at: z.string(),
|
|
777
|
+
});
|
|
778
|
+
|
|
738
779
|
export const flightLogSchema = z.object({
|
|
739
780
|
type: z.literal("flightLog"),
|
|
740
781
|
id: z.number(),
|
|
@@ -749,6 +790,7 @@ export const flightLogSchema = z.object({
|
|
|
749
790
|
booking_id: z.number().nullable().optional(),
|
|
750
791
|
membership_id: z.number().nullable().optional(),
|
|
751
792
|
membership: baseMembershipSchema.optional(),
|
|
793
|
+
billing_profile_id: z.number().nullable().optional(),
|
|
752
794
|
author_id: z.number(),
|
|
753
795
|
author: userSchema.optional(),
|
|
754
796
|
invoice_id: z.number().nullable().optional(),
|
|
@@ -798,6 +840,14 @@ export const invoiceSchema = z.object({
|
|
|
798
840
|
title: z.string(),
|
|
799
841
|
membership_id: z.number(),
|
|
800
842
|
membership: baseMembershipSchema.optional(),
|
|
843
|
+
// InvoiceResource.php always emits `billing_profile_id` (non-optional key,
|
|
844
|
+
// nullable FK value). `billingProfile` is a `whenLoaded('billingProfile')`
|
|
845
|
+
// relation, so it stays optional. (Fix round 1: as of the original Task 16
|
|
846
|
+
// commit, InvoiceResource hadn't gained `billing_profile_id` yet — it was
|
|
847
|
+
// added ~4 minutes later in the same session; tightened here now that the
|
|
848
|
+
// key is always present.)
|
|
849
|
+
billing_profile_id: z.number().nullable(),
|
|
850
|
+
billingProfile: billingProfileSchema.optional(),
|
|
801
851
|
company_id: z.number().optional(),
|
|
802
852
|
company: companySchema.optional(),
|
|
803
853
|
sequence_number: z.string().nullable().optional(),
|
|
@@ -825,6 +875,9 @@ export const invoiceSchema = z.object({
|
|
|
825
875
|
recipient_state: z.string().nullable().optional(),
|
|
826
876
|
recipient_country: z.string().nullable().optional(),
|
|
827
877
|
recipient_vat_id: z.string().nullable().optional(),
|
|
878
|
+
// Always computed by InvoiceResource (billingProfile email, else the
|
|
879
|
+
// membership's user email) — used by InvoiceDialog today but was missing.
|
|
880
|
+
recipient_email: z.string().nullable().optional(),
|
|
828
881
|
issuer_name: z.string().nullable().optional(),
|
|
829
882
|
issuer_address_street_1: z.string().nullable().optional(),
|
|
830
883
|
issuer_address_street_2: z.string().nullable().optional(),
|
|
@@ -1168,6 +1221,8 @@ export const postSchema = z.object({
|
|
|
1168
1221
|
content: z.string(),
|
|
1169
1222
|
sticky: z.boolean().default(false),
|
|
1170
1223
|
public: z.boolean().default(false),
|
|
1224
|
+
comments_disabled: z.boolean().default(false),
|
|
1225
|
+
tags: z.array(tagSchema).optional(),
|
|
1171
1226
|
media: mediaCollection.optional(),
|
|
1172
1227
|
created_at: z.string(),
|
|
1173
1228
|
updated_at: z.string(),
|
|
@@ -1283,17 +1338,90 @@ export const prePaidPackageSchema = z.object({
|
|
|
1283
1338
|
.optional(),
|
|
1284
1339
|
});
|
|
1285
1340
|
|
|
1341
|
+
// A billing line-item (flight charge, landing fee, membership fee, refund,
|
|
1342
|
+
// …) attached to a flight log / booking / membership via the polymorphic
|
|
1343
|
+
// (model_type, model_id) pair, and to an invoice once released. NOT a
|
|
1344
|
+
// catalog entry — rebuilt field-by-field against ExpenseItemResource.php;
|
|
1345
|
+
// the previous shape (name/category/active) modeled a company catalog row,
|
|
1346
|
+
// which ExpenseItem has never had.
|
|
1347
|
+
export const prePaidPackageAssignmentSchema = z.object({
|
|
1348
|
+
id: z.number(),
|
|
1349
|
+
flight_log_id: z.number().nullable().optional(),
|
|
1350
|
+
expense_item_id: z.number().nullable().optional(),
|
|
1351
|
+
pre_paid_package_id: z.number().nullable().optional(),
|
|
1352
|
+
gross_total: zPhpMoneyObject.nullable().optional(),
|
|
1353
|
+
created_at: z.string().nullable().optional(),
|
|
1354
|
+
updated_at: z.string().nullable().optional(),
|
|
1355
|
+
});
|
|
1356
|
+
|
|
1286
1357
|
export const expenseItemSchema = z.object({
|
|
1287
|
-
type
|
|
1358
|
+
// ExpenseItemResource never emits a `type` key; kept optional for
|
|
1359
|
+
// consistency with sibling schemas' discriminated-union literal.
|
|
1360
|
+
type: z.literal("expenseItem").optional(),
|
|
1288
1361
|
id: z.number(),
|
|
1362
|
+
date: z.string(),
|
|
1363
|
+
model_id: z.number(),
|
|
1364
|
+
model_type: z.string(),
|
|
1365
|
+
identifier: z.string().nullable(),
|
|
1366
|
+
// Provenance: the `prices` row this item was generated from. `price_id` is
|
|
1367
|
+
// always present (nullable FK); `price` only when the relation is
|
|
1368
|
+
// eager-loaded.
|
|
1369
|
+
price_id: z.number().nullable(),
|
|
1370
|
+
price: priceSchema.optional(),
|
|
1371
|
+
description: z.string(),
|
|
1372
|
+
description_lines: z.array(z.any()).nullable(),
|
|
1373
|
+
// Resource emits a trimmed decimal string (trailing zeros/dot stripped),
|
|
1374
|
+
// not a number.
|
|
1375
|
+
quantity: z.string(),
|
|
1376
|
+
discount: z.number(),
|
|
1377
|
+
applied_discounts: z.array(z.any()).nullable(),
|
|
1378
|
+
status: z.string(),
|
|
1379
|
+
is_system_controlled: z.boolean(),
|
|
1380
|
+
deferred: z.boolean(),
|
|
1381
|
+
|
|
1382
|
+
invoice_id: z.number().nullable(),
|
|
1289
1383
|
company_id: z.number(),
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1384
|
+
membership_id: z.number(),
|
|
1385
|
+
billing_profile_id: z.number().nullable(),
|
|
1386
|
+
|
|
1387
|
+
gross_total_before_vouchers: zPhpMoneyObject,
|
|
1388
|
+
gross_total: zPhpMoneyObject,
|
|
1389
|
+
net_total: zPhpMoneyObject,
|
|
1390
|
+
tax_total: zPhpMoneyObject,
|
|
1391
|
+
// number_format(…, 2) string, not a number.
|
|
1392
|
+
tax_percentage: z.string(),
|
|
1393
|
+
billable: z.boolean(),
|
|
1394
|
+
meta: z.record(z.string(), z.any()).nullable(),
|
|
1395
|
+
input_value: z.number().nullable(),
|
|
1396
|
+
net_gross: zNetGross,
|
|
1397
|
+
|
|
1398
|
+
refunds_expense_item_id: z.number().nullable(),
|
|
1399
|
+
|
|
1295
1400
|
created_at: z.string(),
|
|
1296
1401
|
updated_at: z.string(),
|
|
1402
|
+
|
|
1403
|
+
// Lazy + explicitly typed as ZodTypeAny (so `invoice` infers as `any`
|
|
1404
|
+
// rather than the full Invoice shape): invoiceSchema is large (60+ fields
|
|
1405
|
+
// incl. media/activities), and this field is additionally reached from
|
|
1406
|
+
// courseEnrollmentSchema/bookingSchema/flightLogSchema via their own lazy
|
|
1407
|
+
// expenseItems refs — inlining the full inferred type here blows past TS's
|
|
1408
|
+
// type-serialization size limit (TS7056: "inferred type … exceeds the
|
|
1409
|
+
// maximum length"). No true cycle: invoiceSchema does not reference
|
|
1410
|
+
// expenseItemSchema back.
|
|
1411
|
+
invoice: z.lazy((): z.ZodTypeAny => invoiceSchema).optional(),
|
|
1412
|
+
membership: baseMembershipSchema.optional(),
|
|
1413
|
+
prePaidPackageAssignments: z
|
|
1414
|
+
.array(prePaidPackageAssignmentSchema)
|
|
1415
|
+
.optional(),
|
|
1416
|
+
// Loose record on purpose: gates are policy-reflected server-side and grow
|
|
1417
|
+
// over time — same convention as companySchema/invoiceSchema.
|
|
1418
|
+
can: z.record(z.string(), z.boolean().nullable()).optional(),
|
|
1419
|
+
|
|
1420
|
+
// Set true only by InvoiceItemSnapshotResource — the immutable,
|
|
1421
|
+
// frozen-at-release line-item shape reused for released/cancelled
|
|
1422
|
+
// invoices (same JSON shape as ExpenseItemResource by design). Absent on
|
|
1423
|
+
// a live ExpenseItemResource payload.
|
|
1424
|
+
is_snapshot: z.boolean().optional(),
|
|
1297
1425
|
});
|
|
1298
1426
|
|
|
1299
1427
|
export const waypointSchema = z.object({
|
package/src/types/ai.ts
CHANGED
package/src/types/models.ts
CHANGED
|
@@ -129,11 +129,26 @@ export type Event = z.infer<typeof ModelSchemas.eventSchema>;
|
|
|
129
129
|
export type Ticket = z.infer<typeof ModelSchemas.ticketSchema>;
|
|
130
130
|
export type Post = z.infer<typeof ModelSchemas.postSchema>;
|
|
131
131
|
|
|
132
|
+
/**
|
|
133
|
+
* Full-replacement tag sync entry — `id` marks an existing tag (wins over
|
|
134
|
+
* name matching), fresh tags carry only name (+ optional color) and are
|
|
135
|
+
* created server-side on save.
|
|
136
|
+
*/
|
|
137
|
+
export interface TagSyncEntry {
|
|
138
|
+
id?: number | null;
|
|
139
|
+
name: string;
|
|
140
|
+
color?: string | null;
|
|
141
|
+
}
|
|
142
|
+
|
|
132
143
|
export interface CreatePostInput {
|
|
133
144
|
title?: string | null;
|
|
134
145
|
content: string;
|
|
135
146
|
sticky?: boolean;
|
|
136
147
|
public?: boolean;
|
|
148
|
+
comments_disabled?: boolean;
|
|
149
|
+
tags?: TagSyncEntry[];
|
|
150
|
+
/** Action flag, not persisted: notify company members on publish. */
|
|
151
|
+
notify?: boolean;
|
|
137
152
|
}
|
|
138
153
|
|
|
139
154
|
export interface UpdatePostInput {
|
|
@@ -141,6 +156,8 @@ export interface UpdatePostInput {
|
|
|
141
156
|
content: string;
|
|
142
157
|
sticky?: boolean;
|
|
143
158
|
public?: boolean;
|
|
159
|
+
comments_disabled?: boolean;
|
|
160
|
+
tags?: TagSyncEntry[];
|
|
144
161
|
}
|
|
145
162
|
|
|
146
163
|
export interface CreateAirplaneIssueInput {
|