@happyvertical/smrt-planner 0.0.0-stage → 0.0.2
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/LICENSE +21 -0
- package/README.md +170 -2
- package/app/404.html +80 -0
- package/app/_app/immutable/assets/0.B5zXkXe_.css +1 -0
- package/app/_app/immutable/assets/10.hpcnxvK1.css +1 -0
- package/app/_app/immutable/assets/11.D7zoXfVV.css +1 -0
- package/app/_app/immutable/assets/12.CPobm1ED.css +1 -0
- package/app/_app/immutable/assets/2.CyaWdRdI.css +1 -0
- package/app/_app/immutable/assets/3.BlPQOes8.css +1 -0
- package/app/_app/immutable/assets/8.2gQeKBp_.css +1 -0
- package/app/_app/immutable/assets/9.HOPT4xtg.css +1 -0
- package/app/_app/immutable/assets/AiSetup.Cb22AigN.css +1 -0
- package/app/_app/immutable/assets/Button.DkP0qkG9.css +1 -0
- package/app/_app/immutable/assets/ConnectTools.BgIJOOGW.css +1 -0
- package/app/_app/immutable/assets/FieldMapForm.BCU-4pO4.css +1 -0
- package/app/_app/immutable/assets/ModelPage.Dd3LcMta.css +1 -0
- package/app/_app/immutable/assets/SectionActions.CTkVuNMF.css +1 -0
- package/app/_app/immutable/assets/SectionIcons.5Udq9vN-.css +1 -0
- package/app/_app/immutable/assets/SegmentedControl.B8SrQacd.css +1 -0
- package/app/_app/immutable/assets/dist.C5nHBk_O.css +1 -0
- package/app/_app/immutable/assets/feedback.BVKAwFck.css +1 -0
- package/app/_app/immutable/assets/forms.BChZ2RWM.css +1 -0
- package/app/_app/immutable/assets/inter-latin-ext.B_-bZUTo.woff2 +0 -0
- package/app/_app/immutable/assets/inter-latin.8kRkwJBP.woff2 +0 -0
- package/app/_app/immutable/assets/jetbrains-mono-latin-ext.Bnd2h4Br.woff2 +0 -0
- package/app/_app/immutable/assets/jetbrains-mono-latin.Db4Uuiha.woff2 +0 -0
- package/app/_app/immutable/assets/ort-wasm-simd-threaded.asyncify.CxOG5pUO.wasm +0 -0
- package/app/_app/immutable/assets/percent.LH0z-ozZ.css +1 -0
- package/app/_app/immutable/assets/space-grotesk-latin-ext.wJGaI8U0.woff2 +0 -0
- package/app/_app/immutable/assets/space-grotesk-latin.DPT1xrvW.woff2 +0 -0
- package/app/_app/immutable/assets/store.CGDwHkkF.css +1 -0
- package/app/_app/immutable/assets/ui.B1A1Zl2p.css +1 -0
- package/app/_app/immutable/assets/workspace.BIMkuZDb.css +1 -0
- package/app/_app/immutable/chunks/1okeBSoq.js +1 -0
- package/app/_app/immutable/chunks/2jFBkS1C.js +1 -0
- package/app/_app/immutable/chunks/6P9zxrzU.js +1 -0
- package/app/_app/immutable/chunks/B32EWqI8.js +9 -0
- package/app/_app/immutable/chunks/B4Kevpe0.js +1 -0
- package/app/_app/immutable/chunks/BJfAXhak.js +3 -0
- package/app/_app/immutable/chunks/BKwRT_1p.js +1 -0
- package/app/_app/immutable/chunks/BQxY8kkL.js +1 -0
- package/app/_app/immutable/chunks/BS4h9ES-.js +1 -0
- package/app/_app/immutable/chunks/BWPhGFHl.js +1 -0
- package/app/_app/immutable/chunks/BYcBM-fh.js +1 -0
- package/app/_app/immutable/chunks/BegKiy2G.js +1 -0
- package/app/_app/immutable/chunks/Bjy-W4x2.js +81 -0
- package/app/_app/immutable/chunks/BnRri03M.js +1 -0
- package/app/_app/immutable/chunks/C7zBd-pD.js +1 -0
- package/app/_app/immutable/chunks/CA-A9Ngs.js +1 -0
- package/app/_app/immutable/chunks/CMhpRMKg.js +1 -0
- package/app/_app/immutable/chunks/CPRHZZeW.js +1 -0
- package/app/_app/immutable/chunks/CRQ1Pmzr.js +1 -0
- package/app/_app/immutable/chunks/CWtfVMDz.js +1 -0
- package/app/_app/immutable/chunks/CgAkqYsL.js +1 -0
- package/app/_app/immutable/chunks/Chyo8rdT.js +3 -0
- package/app/_app/immutable/chunks/Ci0DUht6.js +34 -0
- package/app/_app/immutable/chunks/CmmuWmp6.js +2 -0
- package/app/_app/immutable/chunks/CrFNLK0f.js +1 -0
- package/app/_app/immutable/chunks/CrO3W89x.js +1 -0
- package/app/_app/immutable/chunks/CsprTb3f.js +2 -0
- package/app/_app/immutable/chunks/CyUMm_Wp.js +1 -0
- package/app/_app/immutable/chunks/CygC84VT.js +2 -0
- package/app/_app/immutable/chunks/D0VgZnk1.js +1 -0
- package/app/_app/immutable/chunks/D71UrO5c.js +1 -0
- package/app/_app/immutable/chunks/D7hhQvDO.js +1 -0
- package/app/_app/immutable/chunks/DD7gpKb2.js +1 -0
- package/app/_app/immutable/chunks/DNRgqfTx.js +1 -0
- package/app/_app/immutable/chunks/DRByVC-c.js +1 -0
- package/app/_app/immutable/chunks/DVRKjN-E.js +1 -0
- package/app/_app/immutable/chunks/D_J_XtJy.js +846 -0
- package/app/_app/immutable/chunks/Dbjm4OuC.js +1 -0
- package/app/_app/immutable/chunks/Dc4q22LH.js +42 -0
- package/app/_app/immutable/chunks/Dd_uD5pT.js +1 -0
- package/app/_app/immutable/chunks/DkR8_Ws6.js +2 -0
- package/app/_app/immutable/chunks/Dp9GVO-9.js +1 -0
- package/app/_app/immutable/chunks/DqcD-WtP.js +1 -0
- package/app/_app/immutable/chunks/Dt-HX3Vu.js +1 -0
- package/app/_app/immutable/chunks/FbOxj-PF.js +69 -0
- package/app/_app/immutable/chunks/QukgIHDX.js +1 -0
- package/app/_app/immutable/chunks/WxSPP8QW.js +4 -0
- package/app/_app/immutable/chunks/Xp1g1t4n.js +3 -0
- package/app/_app/immutable/chunks/iET62IRm.js +2 -0
- package/app/_app/immutable/chunks/leQCwW2d.js +1 -0
- package/app/_app/immutable/chunks/p6bgzXiY.js +1 -0
- package/app/_app/immutable/chunks/uBIymjUX.js +1 -0
- package/app/_app/immutable/chunks/xihTtKlq.js +1 -0
- package/app/_app/immutable/entry/app.IZIJXhgq.js +2 -0
- package/app/_app/immutable/entry/start.BuaYHD1N.js +1 -0
- package/app/_app/immutable/nodes/0.m_U8WC7E.js +10 -0
- package/app/_app/immutable/nodes/1.Crw8ULhB.js +1 -0
- package/app/_app/immutable/nodes/10.1nQxyH9H.js +4 -0
- package/app/_app/immutable/nodes/11.Cw0JnQF3.js +1 -0
- package/app/_app/immutable/nodes/12.BIocA1aI.js +1 -0
- package/app/_app/immutable/nodes/2.CR5BwGnt.js +17 -0
- package/app/_app/immutable/nodes/3.1B56hgAG.js +1 -0
- package/app/_app/immutable/nodes/4.SSIC7sUh.js +1 -0
- package/app/_app/immutable/nodes/5.DgdwleDQ.js +1 -0
- package/app/_app/immutable/nodes/6.DmD9rqLU.js +1 -0
- package/app/_app/immutable/nodes/7.DdngsBmo.js +1 -0
- package/app/_app/immutable/nodes/8.D2Mszsua.js +3 -0
- package/app/_app/immutable/nodes/9.CLYsywul.js +1 -0
- package/app/_app/immutable/workers/assets/ort-wasm-simd-threaded.asyncify-CxOG5pUO.wasm +0 -0
- package/app/_app/immutable/workers/llm.worker-wfCOG_uk.js +69 -0
- package/app/_app/immutable/workers/local-speech.worker-DWbfmFUk.js +51 -0
- package/app/_app/version.json +1 -0
- package/app/ai/index.html +89 -0
- package/app/blueprint/index.html +87 -0
- package/app/cookbook/index.html +87 -0
- package/app/index.html +103 -0
- package/app/m/ads/AdDeliveryTier/index.html +96 -0
- package/app/m/ads/AdEvent/index.html +96 -0
- package/app/m/ads/AdFormat/index.html +96 -0
- package/app/m/ads/AdGroup/index.html +96 -0
- package/app/m/ads/AdVariation/index.html +96 -0
- package/app/m/analytics/AnalyticsDataStream/index.html +96 -0
- package/app/m/analytics/AnalyticsEvent/index.html +96 -0
- package/app/m/analytics/AnalyticsProperty/index.html +96 -0
- package/app/m/analytics/AnalyticsReport/index.html +96 -0
- package/app/m/approvals/ApprovalEvent/index.html +96 -0
- package/app/m/approvals/ApprovalPolicy/index.html +96 -0
- package/app/m/approvals/ApprovalRequest/index.html +96 -0
- package/app/m/assets/Asset/index.html +96 -0
- package/app/m/assets/AssetAssociation/index.html +97 -0
- package/app/m/assets/AssetMetafield/index.html +96 -0
- package/app/m/assets/AssetStatus/index.html +96 -0
- package/app/m/assets/AssetType/index.html +96 -0
- package/app/m/assets/Folder/index.html +96 -0
- package/app/m/chat/AgentSession/index.html +96 -0
- package/app/m/chat/ChatMessage/index.html +97 -0
- package/app/m/chat/ChatParticipant/index.html +97 -0
- package/app/m/chat/ChatReaction/index.html +96 -0
- package/app/m/chat/ChatRoom/index.html +96 -0
- package/app/m/chat/ChatThread/index.html +97 -0
- package/app/m/chat/VoiceGatewayTurn/index.html +96 -0
- package/app/m/chat/VoiceSession/index.html +96 -0
- package/app/m/commerce/Agreement/index.html +96 -0
- package/app/m/commerce/Cart/index.html +96 -0
- package/app/m/commerce/Contract/index.html +96 -0
- package/app/m/commerce/ContractLineItem/index.html +97 -0
- package/app/m/commerce/Customer/index.html +96 -0
- package/app/m/commerce/Estimate/index.html +96 -0
- package/app/m/commerce/Fulfillment/index.html +96 -0
- package/app/m/commerce/FulfillmentLineItem/index.html +97 -0
- package/app/m/commerce/Invoice/index.html +96 -0
- package/app/m/commerce/InvoiceLineItem/index.html +97 -0
- package/app/m/commerce/Lease/index.html +96 -0
- package/app/m/commerce/LicenseSale/index.html +96 -0
- package/app/m/commerce/Order/index.html +96 -0
- package/app/m/commerce/Payment/index.html +96 -0
- package/app/m/commerce/PaymentAllocation/index.html +97 -0
- package/app/m/commerce/PaymentInstrument/index.html +96 -0
- package/app/m/commerce/PaymentIntent/index.html +96 -0
- package/app/m/commerce/Payout/index.html +96 -0
- package/app/m/commerce/ProductionOrder/index.html +96 -0
- package/app/m/commerce/PurchaseOrder/index.html +96 -0
- package/app/m/commerce/Vendor/index.html +96 -0
- package/app/m/commerce/WholesaleOrder/index.html +96 -0
- package/app/m/content/Content/index.html +96 -0
- package/app/m/content/ContentContribution/index.html +96 -0
- package/app/m/content/ContentContributionAttachment/index.html +96 -0
- package/app/m/content/ContentContributionRevision/index.html +96 -0
- package/app/m/content/ContentContributionType/index.html +96 -0
- package/app/m/content/ContentContributor/index.html +96 -0
- package/app/m/content/ContentCorrection/index.html +96 -0
- package/app/m/content/ContentFeedSource/index.html +96 -0
- package/app/m/content/ContentGovernanceAssignment/index.html +96 -0
- package/app/m/content/ContentGovernancePolicy/index.html +96 -0
- package/app/m/content/ContentGovernanceProfile/index.html +96 -0
- package/app/m/content/ContentReference/index.html +96 -0
- package/app/m/content/ContentReview/index.html +96 -0
- package/app/m/content/ContentVersion/index.html +96 -0
- package/app/m/content/Contents/index.html +96 -0
- package/app/m/events/Event/index.html +96 -0
- package/app/m/events/EventParticipant/index.html +97 -0
- package/app/m/events/EventSeries/index.html +96 -0
- package/app/m/events/EventType/index.html +96 -0
- package/app/m/facts/Fact/index.html +96 -0
- package/app/m/facts/FactContent/index.html +96 -0
- package/app/m/facts/FactEvidence/index.html +96 -0
- package/app/m/facts/FactSource/index.html +96 -0
- package/app/m/facts/FactSubject/index.html +96 -0
- package/app/m/facts/FactTag/index.html +96 -0
- package/app/m/fields/FieldPolicy/index.html +96 -0
- package/app/m/fields/FieldPolicySuggestion/index.html +96 -0
- package/app/m/fields/FieldUsageCounter/index.html +96 -0
- package/app/m/images/Image/index.html +96 -0
- package/app/m/inventory/InventoryLocation/index.html +96 -0
- package/app/m/inventory/StockLevel/index.html +96 -0
- package/app/m/inventory/StockMovement/index.html +96 -0
- package/app/m/ledgers/Account/index.html +96 -0
- package/app/m/ledgers/Journal/index.html +96 -0
- package/app/m/ledgers/JournalEntry/index.html +97 -0
- package/app/m/manufacturing/Assembly/index.html +96 -0
- package/app/m/manufacturing/BillOfMaterials/index.html +96 -0
- package/app/m/manufacturing/BomLine/index.html +96 -0
- package/app/m/manufacturing/Operation/index.html +96 -0
- package/app/m/manufacturing/ProductionRun/index.html +96 -0
- package/app/m/manufacturing/ProductionRunCompletion/index.html +96 -0
- package/app/m/manufacturing/RoutingStep/index.html +96 -0
- package/app/m/marketing/Campaign/index.html +96 -0
- package/app/m/marketing/CampaignChannel/index.html +96 -0
- package/app/m/marketing/CampaignMetricSnapshot/index.html +96 -0
- package/app/m/messages/Account/index.html +96 -0
- package/app/m/messages/Attachment/index.html +96 -0
- package/app/m/messages/Blacklist/index.html +96 -0
- package/app/m/messages/Email/failed-sends/index.html +96 -0
- package/app/m/messages/Email/index.html +96 -0
- package/app/m/messages/Email/mailbox/index.html +96 -0
- package/app/m/messages/EmailAccount/index.html +96 -0
- package/app/m/messages/EmailFolder/index.html +96 -0
- package/app/m/messages/Message/index.html +96 -0
- package/app/m/messages/MessagingEndpoint/index.html +96 -0
- package/app/m/messages/PersonaMessageRoute/index.html +96 -0
- package/app/m/messages/SlackAccount/index.html +96 -0
- package/app/m/messages/SlackMessage/index.html +96 -0
- package/app/m/messages/TelegramAccount/index.html +96 -0
- package/app/m/messages/Tweet/index.html +96 -0
- package/app/m/messages/TwitterAccount/index.html +96 -0
- package/app/m/messages/Whitelist/index.html +96 -0
- package/app/m/messages/ZulipAccount/index.html +96 -0
- package/app/m/places/Place/index.html +96 -0
- package/app/m/places/PlaceType/index.html +96 -0
- package/app/m/preferences/UiPreferenceRecord/index.html +96 -0
- package/app/m/products/Category/index.html +96 -0
- package/app/m/products/Material/index.html +96 -0
- package/app/m/products/Product/index.html +96 -0
- package/app/m/products/Product/ingredients/index.html +96 -0
- package/app/m/products/ProductVariant/index.html +97 -0
- package/app/m/products/Sku/index.html +97 -0
- package/app/m/profiles/ApiKey/index.html +96 -0
- package/app/m/profiles/Bot/index.html +96 -0
- package/app/m/profiles/MagicLinkToken/index.html +96 -0
- package/app/m/profiles/NostrIdentity/index.html +96 -0
- package/app/m/profiles/OidcIdentity/index.html +96 -0
- package/app/m/profiles/Organization/index.html +96 -0
- package/app/m/profiles/Person/index.html +96 -0
- package/app/m/profiles/Profile/index.html +96 -0
- package/app/m/profiles/ProfileMetadata/index.html +96 -0
- package/app/m/profiles/ProfileMetafield/index.html +96 -0
- package/app/m/profiles/ProfileRelationship/index.html +96 -0
- package/app/m/profiles/ProfileRelationshipTerm/index.html +96 -0
- package/app/m/profiles/ProfileRelationshipType/index.html +96 -0
- package/app/m/profiles/ProfileType/index.html +96 -0
- package/app/m/projects/Comment/index.html +97 -0
- package/app/m/projects/Issue/index.html +96 -0
- package/app/m/projects/Label/index.html +96 -0
- package/app/m/projects/Project/index.html +96 -0
- package/app/m/projects/ProjectIntegration/index.html +96 -0
- package/app/m/projects/PullRequest/index.html +96 -0
- package/app/m/projects/Repository/index.html +96 -0
- package/app/m/properties/Property/index.html +96 -0
- package/app/m/properties/Zone/index.html +96 -0
- package/app/m/reports/RuntimeReport/index.html +96 -0
- package/app/m/reports/SmrtPrincipalReportRefreshTask/index.html +96 -0
- package/app/m/reports/SmrtReportLock/index.html +96 -0
- package/app/m/reports/SmrtReportRefreshTask/index.html +96 -0
- package/app/m/reports/SmrtReportRun/index.html +96 -0
- package/app/m/reports/SmrtReportSchedule/index.html +96 -0
- package/app/m/reports/SmrtReportWatermark/index.html +96 -0
- package/app/m/sales/AttributionException/index.html +96 -0
- package/app/m/sales/AttributionPolicy/index.html +96 -0
- package/app/m/sales/Commission/index.html +96 -0
- package/app/m/sales/CommissionAdjustment/index.html +96 -0
- package/app/m/sales/CommissionPayout/index.html +96 -0
- package/app/m/sales/CommissionPlan/index.html +96 -0
- package/app/m/sales/Earner/index.html +96 -0
- package/app/m/sales/EarnerSourceAttribution/index.html +96 -0
- package/app/m/sales/EarningEvent/index.html +96 -0
- package/app/m/sales/ExecutedAgreement/index.html +96 -0
- package/app/m/sales/Lead/index.html +96 -0
- package/app/m/sales/Opportunity/index.html +96 -0
- package/app/m/sales/OpportunityConversion/index.html +96 -0
- package/app/m/sales/PipelineDefinition/index.html +96 -0
- package/app/m/sales/PipelineStage/index.html +97 -0
- package/app/m/sales/Referral/index.html +96 -0
- package/app/m/sales/ReferralAgreement/index.html +96 -0
- package/app/m/sales/ReferralLink/index.html +96 -0
- package/app/m/sales/ReferralProgram/index.html +96 -0
- package/app/m/sales/ReferralTermSnapshot/index.html +96 -0
- package/app/m/sales/ReferralTouch/index.html +96 -0
- package/app/m/sales/Referrer/index.html +96 -0
- package/app/m/sales/SalesActivity/index.html +96 -0
- package/app/m/sales/SalesRepresentative/index.html +96 -0
- package/app/m/sites/Site/index.html +96 -0
- package/app/m/sites/SiteAgentBinding/index.html +96 -0
- package/app/m/social/OAuthState/index.html +96 -0
- package/app/m/social/SocialAccount/index.html +96 -0
- package/app/m/social/SocialPost/index.html +96 -0
- package/app/m/social/SocialPostAnalyticsSnapshot/index.html +96 -0
- package/app/m/subscriptions/BillingAdjustment/index.html +96 -0
- package/app/m/subscriptions/ClientCharge/index.html +96 -0
- package/app/m/subscriptions/CreditGrant/index.html +96 -0
- package/app/m/subscriptions/PricingRule/index.html +96 -0
- package/app/m/subscriptions/RetailCharge/index.html +96 -0
- package/app/m/subscriptions/SpendingPolicy/index.html +96 -0
- package/app/m/subscriptions/SubscriptionPlan/index.html +96 -0
- package/app/m/subscriptions/TenantSubscription/index.html +96 -0
- package/app/m/subscriptions/TenantUsageMetric/index.html +96 -0
- package/app/m/support/ServiceTimeEntry/index.html +96 -0
- package/app/m/support/SupportAiRun/index.html +96 -0
- package/app/m/support/SupportAvailability/index.html +96 -0
- package/app/m/support/SupportCase/index.html +96 -0
- package/app/m/support/SupportCaseEvent/index.html +96 -0
- package/app/m/support/SupportChannelBinding/index.html +96 -0
- package/app/m/support/SupportCharge/index.html +96 -0
- package/app/m/support/SupportCompensation/index.html +96 -0
- package/app/m/support/SupportCompensationPlan/index.html +96 -0
- package/app/m/support/SupportEscalation/index.html +96 -0
- package/app/m/support/SupportInteraction/index.html +96 -0
- package/app/m/support/SupportPlan/index.html +96 -0
- package/app/m/support/SupportPolicy/index.html +96 -0
- package/app/m/support/SupportQualification/index.html +96 -0
- package/app/m/support/SupportServiceTarget/index.html +96 -0
- package/app/m/support/SupportSpecialist/index.html +96 -0
- package/app/m/support/SupportWorkLink/index.html +96 -0
- package/app/m/tags/Tag/index.html +96 -0
- package/app/m/tags/TagAlias/index.html +96 -0
- package/app/m/timesheets/AttendanceBreak/index.html +96 -0
- package/app/m/timesheets/AttendancePunch/index.html +96 -0
- package/app/m/timesheets/ServiceChargeSnapshot/index.html +96 -0
- package/app/m/timesheets/ServiceCompensationSnapshot/index.html +96 -0
- package/app/m/timesheets/ServiceTimeEntry/index.html +96 -0
- package/app/m/users/AccessRequest/index.html +96 -0
- package/app/m/users/Group/index.html +96 -0
- package/app/m/users/GroupMember/index.html +96 -0
- package/app/m/users/GroupRole/index.html +96 -0
- package/app/m/users/Membership/index.html +97 -0
- package/app/m/users/MembershipOverride/index.html +96 -0
- package/app/m/users/Permission/index.html +96 -0
- package/app/m/users/ResourceGrant/index.html +96 -0
- package/app/m/users/Role/index.html +96 -0
- package/app/m/users/RolePermission/index.html +96 -0
- package/app/m/users/Session/index.html +96 -0
- package/app/m/users/Tenant/index.html +96 -0
- package/app/m/users/TenantIntegration/index.html +96 -0
- package/app/m/users/TenantPermissionOverride/index.html +96 -0
- package/app/m/users/User/index.html +96 -0
- package/app/m/users/UsersCliAuthRequest/index.html +96 -0
- package/app/m/users/UsersMagicLinkToken/index.html +96 -0
- package/app/m/video/Character/index.html +96 -0
- package/app/m/video/CharacterAsset/index.html +96 -0
- package/app/m/video/CompositeJob/index.html +96 -0
- package/app/m/video/Performer/index.html +96 -0
- package/app/m/video/PerformerAsset/index.html +96 -0
- package/app/m/video/Scene/index.html +96 -0
- package/app/m/video/SceneAsset/index.html +96 -0
- package/app/m/video/VideoComposition/index.html +96 -0
- package/app/m/video/VideoCompositionAsset/index.html +96 -0
- package/app/m/video/VideoSequence/index.html +96 -0
- package/app/m/video/VideoSequenceAsset/index.html +96 -0
- package/app/m/video/VideoShot/index.html +96 -0
- package/app/m/video/VideoShotAsset/index.html +96 -0
- package/app/m/video/VideoShotCharacter/index.html +96 -0
- package/app/m/video/VideoWorkflow/index.html +96 -0
- package/app/m/voice/VoiceOutput/index.html +96 -0
- package/app/m/voice/VoiceProfile/index.html +96 -0
- package/app/m/voice/VoiceSample/index.html +96 -0
- package/app/packages/ads/index.html +92 -0
- package/app/packages/analytics/index.html +92 -0
- package/app/packages/approvals/index.html +92 -0
- package/app/packages/assets/index.html +92 -0
- package/app/packages/chat/index.html +92 -0
- package/app/packages/comments/index.html +92 -0
- package/app/packages/commerce/index.html +92 -0
- package/app/packages/content/index.html +92 -0
- package/app/packages/events/index.html +92 -0
- package/app/packages/expenses/index.html +92 -0
- package/app/packages/facts/index.html +92 -0
- package/app/packages/fields/index.html +92 -0
- package/app/packages/human-resources/index.html +92 -0
- package/app/packages/images/index.html +92 -0
- package/app/packages/index.html +90 -0
- package/app/packages/inventory/index.html +92 -0
- package/app/packages/ledgers/index.html +92 -0
- package/app/packages/manufacturing/index.html +92 -0
- package/app/packages/marketing/index.html +92 -0
- package/app/packages/messages/index.html +92 -0
- package/app/packages/places/index.html +92 -0
- package/app/packages/preferences/index.html +92 -0
- package/app/packages/products/index.html +92 -0
- package/app/packages/profiles/index.html +92 -0
- package/app/packages/projects/index.html +92 -0
- package/app/packages/properties/index.html +92 -0
- package/app/packages/reports/index.html +92 -0
- package/app/packages/sales/index.html +92 -0
- package/app/packages/sites/index.html +92 -0
- package/app/packages/social/index.html +92 -0
- package/app/packages/subscriptions/index.html +92 -0
- package/app/packages/support/index.html +92 -0
- package/app/packages/tags/index.html +92 -0
- package/app/packages/timesheets/index.html +92 -0
- package/app/packages/users/index.html +92 -0
- package/app/packages/video/index.html +92 -0
- package/app/packages/voice/index.html +92 -0
- package/app/recipes/account-access/help/index.html +93 -0
- package/app/recipes/account-access/index.html +95 -0
- package/app/recipes/activity/help/index.html +93 -0
- package/app/recipes/activity/index.html +94 -0
- package/app/recipes/agreements/help/index.html +93 -0
- package/app/recipes/agreements/index.html +96 -0
- package/app/recipes/analytics.reports/help/index.html +93 -0
- package/app/recipes/analytics.reports/index.html +94 -0
- package/app/recipes/assets/help/index.html +93 -0
- package/app/recipes/assets/index.html +95 -0
- package/app/recipes/billing/help/index.html +93 -0
- package/app/recipes/billing/index.html +95 -0
- package/app/recipes/chat.assistant/help/index.html +93 -0
- package/app/recipes/chat.assistant/index.html +94 -0
- package/app/recipes/comments/help/index.html +93 -0
- package/app/recipes/comments/index.html +94 -0
- package/app/recipes/commerce.customers/help/index.html +93 -0
- package/app/recipes/commerce.customers/index.html +94 -0
- package/app/recipes/commerce.estimates/help/index.html +93 -0
- package/app/recipes/commerce.estimates/index.html +94 -0
- package/app/recipes/commerce.purchases/help/index.html +93 -0
- package/app/recipes/commerce.purchases/index.html +94 -0
- package/app/recipes/commerce.sales/help/index.html +93 -0
- package/app/recipes/commerce.sales/index.html +94 -0
- package/app/recipes/commerce.vendors/help/index.html +93 -0
- package/app/recipes/commerce.vendors/index.html +94 -0
- package/app/recipes/commerce.wholesale/help/index.html +93 -0
- package/app/recipes/commerce.wholesale/index.html +94 -0
- package/app/recipes/events.calendar/help/index.html +93 -0
- package/app/recipes/events.calendar/index.html +94 -0
- package/app/recipes/fields.form-customization/help/index.html +93 -0
- package/app/recipes/fields.form-customization/index.html +94 -0
- package/app/recipes/inventory.stock/help/index.html +93 -0
- package/app/recipes/inventory.stock/index.html +94 -0
- package/app/recipes/ledgers.bookkeeping/help/index.html +93 -0
- package/app/recipes/ledgers.bookkeeping/index.html +94 -0
- package/app/recipes/messages/help/index.html +93 -0
- package/app/recipes/messages/index.html +95 -0
- package/app/recipes/products/help/index.html +93 -0
- package/app/recipes/products/index.html +96 -0
- package/app/recipes/projects.tracker/help/index.html +93 -0
- package/app/recipes/projects.tracker/index.html +94 -0
- package/app/recipes/reports.materialized/help/index.html +93 -0
- package/app/recipes/reports.materialized/index.html +94 -0
- package/app/recipes/sales.pipeline/help/index.html +93 -0
- package/app/recipes/sales.pipeline/index.html +94 -0
- package/app/recipes/tags.taxonomy/help/index.html +93 -0
- package/app/recipes/tags.taxonomy/index.html +94 -0
- package/app/recipes/team-collaboration/help/index.html +93 -0
- package/app/recipes/team-collaboration/index.html +94 -0
- package/app/s/custom-billing/index.html +89 -0
- package/app/s/custom-buying/index.html +89 -0
- package/app/s/custom-classes/index.html +89 -0
- package/app/s/custom-jobs/index.html +89 -0
- package/app/s/custom-kitchen/index.html +89 -0
- package/app/s/custom-material/index.html +89 -0
- package/app/s/custom-members/index.html +89 -0
- package/app/s/custom-parts/index.html +89 -0
- package/app/s/custom-schedule/index.html +89 -0
- package/app/s/custom-shop/index.html +89 -0
- package/app/s/custom-wholesale/index.html +89 -0
- package/app/s/section-access-control/index.html +89 -0
- package/app/s/section-account-security/index.html +89 -0
- package/app/s/section-accounting/index.html +89 -0
- package/app/s/section-activity/index.html +89 -0
- package/app/s/section-agreements/index.html +89 -0
- package/app/s/section-analytics/index.html +89 -0
- package/app/s/section-assets/index.html +89 -0
- package/app/s/section-billing/index.html +89 -0
- package/app/s/section-calendar/index.html +89 -0
- package/app/s/section-catalog/index.html +89 -0
- package/app/s/section-chat.assistant/index.html +89 -0
- package/app/s/section-comments/index.html +89 -0
- package/app/s/section-fields.form-customization/index.html +89 -0
- package/app/s/section-messages/index.html +89 -0
- package/app/s/section-more/index.html +89 -0
- package/app/s/section-operations/index.html +89 -0
- package/app/s/section-projects/index.html +89 -0
- package/app/s/section-purchasing/index.html +89 -0
- package/app/s/section-reports.materialized/index.html +89 -0
- package/app/s/section-sales/index.html +89 -0
- package/app/s/section-taxonomy/index.html +89 -0
- package/app/s/section-team/index.html +89 -0
- package/dist/ai/echo-gate.d.ts +13 -0
- package/dist/ai/echo-gate.js +21 -0
- package/dist/ai/icons.d.ts +9 -0
- package/dist/ai/icons.js +9 -0
- package/dist/ai/instance.d.ts +3 -0
- package/dist/ai/instance.js +25 -0
- package/dist/ai/state.svelte.d.ts +130 -0
- package/dist/ai/state.svelte.js +316 -0
- package/dist/ai/status.d.ts +67 -0
- package/dist/ai/status.js +125 -0
- package/dist/assets/smrt-mark.svg +38 -0
- package/dist/assistant/change.d.ts +101 -0
- package/dist/assistant/change.js +209 -0
- package/dist/assistant/engine.d.ts +20 -0
- package/dist/assistant/engine.js +43 -0
- package/dist/assistant/llm.worker.d.ts +1 -0
- package/dist/assistant/llm.worker.js +7 -0
- package/dist/assistant/match.d.ts +59 -0
- package/dist/assistant/match.js +271 -0
- package/dist/assistant/models.d.ts +38 -0
- package/dist/assistant/models.js +57 -0
- package/dist/assistant/offers.svelte.d.ts +36 -0
- package/dist/assistant/offers.svelte.js +59 -0
- package/dist/assistant/prefs.d.ts +14 -0
- package/dist/assistant/prefs.js +32 -0
- package/dist/assistant/prompt.d.ts +23 -0
- package/dist/assistant/prompt.js +163 -0
- package/dist/assistant/session.svelte.d.ts +74 -0
- package/dist/assistant/session.svelte.js +181 -0
- package/dist/assistant/theme-undo.svelte.d.ts +38 -0
- package/dist/assistant/theme-undo.svelte.js +50 -0
- package/dist/assistant/transport.d.ts +73 -0
- package/dist/assistant/transport.js +231 -0
- package/dist/assistant/voice-host.d.ts +10 -0
- package/dist/assistant/voice-host.js +17 -0
- package/dist/assistant/voice.svelte.d.ts +107 -0
- package/dist/assistant/voice.svelte.js +261 -0
- package/dist/catalog/catalog.json +89663 -0
- package/dist/catalog/generate/build.d.ts +33 -0
- package/dist/catalog/generate/build.js +131 -0
- package/dist/catalog/generate/exclusions.d.ts +18 -0
- package/dist/catalog/generate/exclusions.js +33 -0
- package/dist/catalog/generate/extract.d.ts +90 -0
- package/dist/catalog/generate/extract.js +326 -0
- package/dist/catalog/generate/local.d.ts +8 -0
- package/dist/catalog/generate/local.js +45 -0
- package/dist/catalog/generate/recipe-demo.d.ts +11 -0
- package/dist/catalog/generate/recipe-demo.js +29 -0
- package/dist/catalog/generate/recipe-metadata.d.ts +12 -0
- package/dist/catalog/generate/recipe-metadata.js +138 -0
- package/dist/catalog/generate/registry.d.ts +14 -0
- package/dist/catalog/generate/registry.js +83 -0
- package/dist/catalog/index.d.ts +21 -0
- package/dist/catalog/index.js +53 -0
- package/dist/catalog/types.d.ts +141 -0
- package/dist/catalog/types.js +8 -0
- package/dist/components/AiSetup.svelte +528 -0
- package/dist/components/AiSetup.svelte.d.ts +8 -0
- package/dist/components/AiStatusIcons.svelte +86 -0
- package/dist/components/AiStatusIcons.svelte.d.ts +18 -0
- package/dist/components/AppSettings.svelte +100 -0
- package/dist/components/AppSettings.svelte.d.ts +10 -0
- package/dist/components/BrowserAssistant.svelte +318 -0
- package/dist/components/BrowserAssistant.svelte.d.ts +8 -0
- package/dist/components/ChildRecords.svelte +331 -0
- package/dist/components/ChildRecords.svelte.d.ts +15 -0
- package/dist/components/ConnectTools.svelte +145 -0
- package/dist/components/ConnectTools.svelte.d.ts +8 -0
- package/dist/components/CookbooksPanel.svelte +308 -0
- package/dist/components/CookbooksPanel.svelte.d.ts +3 -0
- package/dist/components/ExportPanel.svelte +217 -0
- package/dist/components/ExportPanel.svelte.d.ts +3 -0
- package/dist/components/FeatureCard.svelte +197 -0
- package/dist/components/FeatureCard.svelte.d.ts +13 -0
- package/dist/components/FeaturesPanel.svelte +155 -0
- package/dist/components/FeaturesPanel.svelte.d.ts +3 -0
- package/dist/components/FieldInput.svelte +307 -0
- package/dist/components/FieldInput.svelte.d.ts +24 -0
- package/dist/components/FieldMapForm.svelte +173 -0
- package/dist/components/FieldMapForm.svelte.d.ts +18 -0
- package/dist/components/FormWorkspace.svelte +274 -0
- package/dist/components/FormWorkspace.svelte.d.ts +19 -0
- package/dist/components/HelpView.svelte +129 -0
- package/dist/components/HelpView.svelte.d.ts +12 -0
- package/dist/components/ModelOptions.svelte +239 -0
- package/dist/components/ModelOptions.svelte.d.ts +12 -0
- package/dist/components/ModelPage.svelte +295 -0
- package/dist/components/ModelPage.svelte.d.ts +9 -0
- package/dist/components/ModelWorkspace.svelte +488 -0
- package/dist/components/ModelWorkspace.svelte.d.ts +32 -0
- package/dist/components/PlannerEditBridge.svelte +36 -0
- package/dist/components/PlannerEditBridge.svelte.d.ts +3 -0
- package/dist/components/PlannerPalette.svelte +38 -0
- package/dist/components/PlannerPalette.svelte.d.ts +18 -0
- package/dist/components/RecipeCards.svelte +145 -0
- package/dist/components/RecipeCards.svelte.d.ts +3 -0
- package/dist/components/RecipeHelp.svelte +54 -0
- package/dist/components/RecipeHelp.svelte.d.ts +9 -0
- package/dist/components/RecipeOptions.svelte +160 -0
- package/dist/components/RecipeOptions.svelte.d.ts +9 -0
- package/dist/components/RecordFeatures.svelte +240 -0
- package/dist/components/RecordFeatures.svelte.d.ts +3 -0
- package/dist/components/RelationField.svelte +175 -0
- package/dist/components/RelationField.svelte.d.ts +16 -0
- package/dist/components/SectionActions.svelte +91 -0
- package/dist/components/SectionActions.svelte.d.ts +12 -0
- package/dist/components/SectionIcons.svelte +98 -0
- package/dist/components/SectionIcons.svelte.d.ts +15 -0
- package/dist/components/SectionOverview.svelte +65 -0
- package/dist/components/SectionOverview.svelte.d.ts +14 -0
- package/dist/components/SectionPage.svelte +230 -0
- package/dist/components/SectionPage.svelte.d.ts +7 -0
- package/dist/components/SettingsPanel.svelte +60 -0
- package/dist/components/SettingsPanel.svelte.d.ts +7 -0
- package/dist/components/ThemeBridge.svelte +56 -0
- package/dist/components/ThemeBridge.svelte.d.ts +3 -0
- package/dist/components/ThemeSection.svelte +167 -0
- package/dist/components/ThemeSection.svelte.d.ts +11 -0
- package/dist/components/VariantGridForm.svelte +309 -0
- package/dist/components/VariantGridForm.svelte.d.ts +12 -0
- package/dist/components/VoiceTyping.svelte +108 -0
- package/dist/components/VoiceTyping.svelte.d.ts +7 -0
- package/dist/cookbook/assemble.d.ts +16 -0
- package/dist/cookbook/assemble.js +29 -0
- package/dist/cookbook/file.d.ts +7 -0
- package/dist/cookbook/file.js +25 -0
- package/dist/cookbook/legacy.d.ts +9 -0
- package/dist/cookbook/legacy.js +87 -0
- package/dist/cookbook/migrate.d.ts +22 -0
- package/dist/cookbook/migrate.js +106 -0
- package/dist/cookbook/parse.d.ts +16 -0
- package/dist/cookbook/parse.js +246 -0
- package/dist/cookbook/storage.d.ts +45 -0
- package/dist/cookbook/storage.js +98 -0
- package/dist/cookbook/store.svelte.d.ts +94 -0
- package/dist/cookbook/store.svelte.js +231 -0
- package/dist/cookbook/types.d.ts +76 -0
- package/dist/cookbook/types.js +11 -0
- package/dist/cookbook/validate.d.ts +14 -0
- package/dist/cookbook/validate.js +29 -0
- package/dist/core/app.d.ts +37 -0
- package/dist/core/app.js +119 -0
- package/dist/core/catalog.d.ts +19 -0
- package/dist/core/catalog.js +9 -0
- package/dist/core/headless.d.ts +52 -0
- package/dist/core/headless.js +39 -0
- package/dist/core/index.d.ts +28 -0
- package/dist/core/index.js +28 -0
- package/dist/core/prompt.d.ts +38 -0
- package/dist/core/prompt.js +95 -0
- package/dist/core/reply.d.ts +60 -0
- package/dist/core/reply.js +89 -0
- package/dist/core/request.d.ts +15 -0
- package/dist/core/request.js +55 -0
- package/dist/data/children.d.ts +20 -0
- package/dist/data/children.js +80 -0
- package/dist/data/columns.d.ts +56 -0
- package/dist/data/columns.js +150 -0
- package/dist/data/context.d.ts +8 -0
- package/dist/data/context.js +19 -0
- package/dist/data/derived.d.ts +79 -0
- package/dist/data/derived.js +139 -0
- package/dist/data/display.d.ts +23 -0
- package/dist/data/display.js +84 -0
- package/dist/data/fakes.d.ts +52 -0
- package/dist/data/fakes.js +443 -0
- package/dist/data/format.d.ts +48 -0
- package/dist/data/format.js +121 -0
- package/dist/data/labels.d.ts +45 -0
- package/dist/data/labels.js +179 -0
- package/dist/data/packs.d.ts +95 -0
- package/dist/data/packs.js +830 -0
- package/dist/data/payments.d.ts +17 -0
- package/dist/data/payments.js +60 -0
- package/dist/data/planner-source.d.ts +7 -0
- package/dist/data/planner-source.js +32 -0
- package/dist/data/source.d.ts +119 -0
- package/dist/data/source.js +432 -0
- package/dist/features/catalogue.d.ts +96 -0
- package/dist/features/catalogue.js +225 -0
- package/dist/features/demo.d.ts +36 -0
- package/dist/features/demo.js +66 -0
- package/dist/features/palette.d.ts +39 -0
- package/dist/features/palette.js +53 -0
- package/dist/fields/address.d.ts +23 -0
- package/dist/fields/address.js +39 -0
- package/dist/fields/invalid.d.ts +2 -0
- package/dist/fields/invalid.js +8 -0
- package/dist/fields/modal.d.ts +7 -0
- package/dist/fields/modal.js +14 -0
- package/dist/fields/percent.d.ts +8 -0
- package/dist/fields/percent.js +16 -0
- package/dist/fields/renderer.d.ts +17 -0
- package/dist/fields/renderer.js +43 -0
- package/dist/forms/active.d.ts +16 -0
- package/dist/forms/active.js +24 -0
- package/dist/forms/fieldMap.d.ts +44 -0
- package/dist/forms/fieldMap.js +134 -0
- package/dist/forms/shared.d.ts +41 -0
- package/dist/forms/shared.js +138 -0
- package/dist/forms/stock.d.ts +28 -0
- package/dist/forms/stock.js +104 -0
- package/dist/forms/variantGrid.d.ts +83 -0
- package/dist/forms/variantGrid.js +283 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +16 -0
- package/dist/inference/byo.svelte.d.ts +90 -0
- package/dist/inference/byo.svelte.js +295 -0
- package/dist/inference/config.d.ts +77 -0
- package/dist/inference/config.js +205 -0
- package/dist/inference/host.d.ts +40 -0
- package/dist/inference/host.js +57 -0
- package/dist/inference/openai.d.ts +59 -0
- package/dist/inference/openai.js +207 -0
- package/dist/inference/presets.d.ts +5 -0
- package/dist/inference/presets.js +46 -0
- package/dist/kitchen/client.d.ts +39 -0
- package/dist/kitchen/client.js +115 -0
- package/dist/kitchen/fragment.d.ts +30 -0
- package/dist/kitchen/fragment.js +49 -0
- package/dist/kitchen/state.svelte.d.ts +26 -0
- package/dist/kitchen/state.svelte.js +45 -0
- package/dist/library/apply.d.ts +17 -0
- package/dist/library/apply.js +32 -0
- package/dist/library/document.d.ts +12 -0
- package/dist/library/document.js +27 -0
- package/dist/library/icons.d.ts +6 -0
- package/dist/library/icons.js +26 -0
- package/dist/library/index.d.ts +8 -0
- package/dist/library/index.js +12 -0
- package/dist/library/library.json +788 -0
- package/dist/library/menu.d.ts +18 -0
- package/dist/library/menu.js +72 -0
- package/dist/library/state.svelte.d.ts +10 -0
- package/dist/library/state.svelte.js +28 -0
- package/dist/library/types.d.ts +57 -0
- package/dist/library/types.js +1 -0
- package/dist/overviews/definitions.d.ts +24 -0
- package/dist/overviews/definitions.js +97 -0
- package/dist/overviews/page.d.ts +21 -0
- package/dist/overviews/page.js +36 -0
- package/dist/overviews/registry.d.ts +44 -0
- package/dist/overviews/registry.js +191 -0
- package/dist/overviews/validate.d.ts +32 -0
- package/dist/overviews/validate.js +91 -0
- package/dist/planner/Planner.svelte +204 -0
- package/dist/planner/Planner.svelte.d.ts +4 -0
- package/dist/planner/app.svelte.d.ts +6 -0
- package/dist/planner/app.svelte.js +23 -0
- package/dist/planner/assistant.d.ts +46 -0
- package/dist/planner/assistant.js +122 -0
- package/dist/planner/commands/adapter.d.ts +121 -0
- package/dist/planner/commands/adapter.js +597 -0
- package/dist/planner/commands/catalog.d.ts +19 -0
- package/dist/planner/commands/catalog.js +54 -0
- package/dist/planner/commands/controller.svelte.d.ts +13 -0
- package/dist/planner/commands/controller.svelte.js +77 -0
- package/dist/planner/commands/index.d.ts +15 -0
- package/dist/planner/commands/index.js +15 -0
- package/dist/planner/commands/schemas.d.ts +25 -0
- package/dist/planner/commands/schemas.js +67 -0
- package/dist/planner/commands/slices.d.ts +18 -0
- package/dist/planner/commands/slices.js +49 -0
- package/dist/planner/commands/types.d.ts +80 -0
- package/dist/planner/commands/types.js +18 -0
- package/dist/planner/create.d.ts +4 -0
- package/dist/planner/create.js +22 -0
- package/dist/planner/instance.d.ts +15 -0
- package/dist/planner/instance.js +22 -0
- package/dist/planner/query.d.ts +16 -0
- package/dist/planner/query.js +28 -0
- package/dist/planner/selection.d.ts +15 -0
- package/dist/planner/selection.js +38 -0
- package/dist/planner/selection.svelte.d.ts +29 -0
- package/dist/planner/selection.svelte.js +54 -0
- package/dist/planner/tab.svelte.d.ts +11 -0
- package/dist/planner/tab.svelte.js +22 -0
- package/dist/planner/types.d.ts +41 -0
- package/dist/planner/types.js +1 -0
- package/dist/recipes/cards.d.ts +55 -0
- package/dist/recipes/cards.js +80 -0
- package/dist/recipes/features.d.ts +53 -0
- package/dist/recipes/features.js +97 -0
- package/dist/recipes/help/descriptions.json +373 -0
- package/dist/recipes/help.d.ts +121 -0
- package/dist/recipes/help.js +262 -0
- package/dist/recipes/index.d.ts +65 -0
- package/dist/recipes/index.js +95 -0
- package/dist/recipes/merge.d.ts +26 -0
- package/dist/recipes/merge.js +21 -0
- package/dist/recipes/overlay.json +409 -0
- package/dist/recipes/plan-data.d.ts +41 -0
- package/dist/recipes/plan-data.js +97 -0
- package/dist/recipes/plumbing.d.ts +70 -0
- package/dist/recipes/plumbing.js +185 -0
- package/dist/recipes/policy.d.ts +118 -0
- package/dist/recipes/policy.js +268 -0
- package/dist/recipes/resolve.d.ts +19 -0
- package/dist/recipes/resolve.js +65 -0
- package/dist/recipes/scope.d.ts +25 -0
- package/dist/recipes/scope.js +31 -0
- package/dist/recipes/sections.d.ts +49 -0
- package/dist/recipes/sections.js +84 -0
- package/dist/recipes/state.svelte.d.ts +67 -0
- package/dist/recipes/state.svelte.js +112 -0
- package/dist/recipes/types.d.ts +322 -0
- package/dist/recipes/types.js +8 -0
- package/dist/sections/entries.d.ts +30 -0
- package/dist/sections/entries.js +57 -0
- package/dist/sections/info.d.ts +16 -0
- package/dist/sections/info.js +39 -0
- package/dist/sections/path.d.ts +12 -0
- package/dist/sections/path.js +18 -0
- package/dist/settings/app-settings.d.ts +44 -0
- package/dist/settings/app-settings.js +138 -0
- package/dist/settings/currencies.d.ts +2 -0
- package/dist/settings/currencies.js +8 -0
- package/dist/theme/runtime.d.ts +14 -0
- package/dist/theme/runtime.js +27 -0
- package/dist/theme/theme.d.ts +47 -0
- package/dist/theme/theme.js +122 -0
- package/dist/upstream/CustomerSelect.svelte +60 -0
- package/dist/upstream/CustomerSelect.svelte.d.ts +17 -0
- package/dist/upstream/VendorSelect.svelte +60 -0
- package/dist/upstream/VendorSelect.svelte.d.ts +17 -0
- package/dist/upstream/overlay.d.ts +10 -0
- package/dist/upstream/overlay.js +49 -0
- package/dist/upstream/partySelect.d.ts +8 -0
- package/dist/upstream/partySelect.js +21 -0
- package/dist/upstream/partyTypes.d.ts +64 -0
- package/dist/upstream/partyTypes.js +8 -0
- package/dist/upstream/relations.d.ts +2 -0
- package/dist/upstream/relations.js +24 -0
- package/dist/upstream/selects.d.ts +26 -0
- package/dist/upstream/selects.js +20 -0
- package/dist/upstream/widgets.d.ts +20 -0
- package/dist/upstream/widgets.js +30 -0
- package/package.json +81 -3
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CatalogModel } from '../catalog/types.ts';
|
|
2
|
+
import { type ModelRecord } from './fakes.ts';
|
|
3
|
+
export interface AllocationSpec {
|
|
4
|
+
/** The allocation model (a payment applied to an invoice). */
|
|
5
|
+
model: CatalogModel;
|
|
6
|
+
paymentFk: string;
|
|
7
|
+
invoiceFk: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Sample payment allocations that add up. Each allocation links one completed
|
|
11
|
+
* payment to one invoice of the same customer, is no more than what the
|
|
12
|
+
* invoice still owes or the payment can cover, and is dated the day the payment
|
|
13
|
+
* was made, never before the invoice was issued. A payment that is pending,
|
|
14
|
+
* failed, refunded or cancelled applies to nothing. Payments are adjusted in
|
|
15
|
+
* place to match what they were applied to (amount, date, contract).
|
|
16
|
+
*/
|
|
17
|
+
export declare function fakeAllocations(spec: AllocationSpec, payments: ModelRecord[], invoices: readonly ModelRecord[], seed: number): ModelRecord[];
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { PAID_PAYMENT_STATUS } from "./derived.js";
|
|
2
|
+
import { createRandom, DAY, EPOCH, fakeId, fakeRecord, hashString, } from "./fakes.js";
|
|
3
|
+
const num = (v) => typeof v === 'number' && Number.isFinite(v) ? v : 0;
|
|
4
|
+
/** Invoices that can be paid: sent out, with something owing. */
|
|
5
|
+
const billable = (invoice) => invoice.status !== 'draft' &&
|
|
6
|
+
invoice.status !== 'cancelled' &&
|
|
7
|
+
num(invoice.totalAmount) > 0;
|
|
8
|
+
/**
|
|
9
|
+
* Sample payment allocations that add up. Each allocation links one completed
|
|
10
|
+
* payment to one invoice of the same customer, is no more than what the
|
|
11
|
+
* invoice still owes or the payment can cover, and is dated the day the payment
|
|
12
|
+
* was made, never before the invoice was issued. A payment that is pending,
|
|
13
|
+
* failed, refunded or cancelled applies to nothing. Payments are adjusted in
|
|
14
|
+
* place to match what they were applied to (amount, date, contract).
|
|
15
|
+
*/
|
|
16
|
+
export function fakeAllocations(spec, payments, invoices, seed) {
|
|
17
|
+
const owed = new Map(invoices.map((inv) => [inv.id, num(inv.totalAmount)]));
|
|
18
|
+
const rows = [];
|
|
19
|
+
for (const payment of payments) {
|
|
20
|
+
if (payment.status !== PAID_PAYMENT_STATUS) {
|
|
21
|
+
if (payment.status !== 'refunded')
|
|
22
|
+
payment.paidAt = null;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const random = createRandom(hashString(`${seed}:alloc:${payment.id}`));
|
|
26
|
+
const open = invoices.filter((inv) => billable(inv) &&
|
|
27
|
+
inv.customerId === payment.customerId &&
|
|
28
|
+
(owed.get(inv.id) ?? 0) > 0);
|
|
29
|
+
const chosen = open.slice(0, random() < 0.3 ? 2 : 1);
|
|
30
|
+
if (chosen.length === 0)
|
|
31
|
+
continue;
|
|
32
|
+
const parts = chosen.map((inv, i) => {
|
|
33
|
+
const balance = owed.get(inv.id) ?? 0;
|
|
34
|
+
// The first invoice is often paid in full, otherwise about half.
|
|
35
|
+
const part = i > 0 || random() < 0.6
|
|
36
|
+
? balance
|
|
37
|
+
: Math.min(balance, Math.max(100, Math.round((balance * (0.3 + random() * 0.4)) / 100) * 100));
|
|
38
|
+
owed.set(inv.id, balance - part);
|
|
39
|
+
return { inv, part };
|
|
40
|
+
});
|
|
41
|
+
const issued = Math.max(...parts.map(({ inv }) => Date.parse(String(inv.issueDate))));
|
|
42
|
+
const paidAt = new Date(Math.max(issued, Math.min(issued + (1 + Math.floor(random() * 20)) * DAY, EPOCH))).toISOString();
|
|
43
|
+
payment.amount = parts.reduce((sum, p) => sum + p.part, 0);
|
|
44
|
+
payment.paidAt = paidAt;
|
|
45
|
+
if ('contractId' in payment && parts[0]?.inv.contractId) {
|
|
46
|
+
payment.contractId = parts[0].inv.contractId;
|
|
47
|
+
}
|
|
48
|
+
for (const { inv, part } of parts) {
|
|
49
|
+
rows.push({
|
|
50
|
+
...fakeRecord(spec.model, rows.length, seed),
|
|
51
|
+
id: fakeId(`${spec.model.id}:${payment.id}:${inv.id}`),
|
|
52
|
+
[spec.paymentFk]: payment.id,
|
|
53
|
+
[spec.invoiceFk]: inv.id,
|
|
54
|
+
amount: part,
|
|
55
|
+
allocatedAt: paidAt,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return rows;
|
|
60
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type DataSource } from './source.ts';
|
|
2
|
+
/**
|
|
3
|
+
* The planner's sample-data source: seeded in-memory fakes whose added, edited
|
|
4
|
+
* and deleted rows survive a reload (Reset clears them). The seam for live
|
|
5
|
+
* objects: swap this for a collection-backed `DataSource`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function createPlannerDataSource(): DataSource;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { catalog } from "../catalog/index.js";
|
|
2
|
+
import { browserStorage } from "../cookbook/storage.js";
|
|
3
|
+
import { catalogModels } from "../forms/shared.js";
|
|
4
|
+
import { PROFILE_TYPE, stockSamples, VARIANT } from "../forms/stock.js";
|
|
5
|
+
import { recipes } from "../recipes/index.js";
|
|
6
|
+
import { childLinks } from "../recipes/plumbing.js";
|
|
7
|
+
import { recipeState } from "../recipes/state.svelte.js";
|
|
8
|
+
import { createMemoryDataSource } from "./source.js";
|
|
9
|
+
/**
|
|
10
|
+
* The planner's sample-data source: seeded in-memory fakes whose added, edited
|
|
11
|
+
* and deleted rows survive a reload (Reset clears them). The seam for live
|
|
12
|
+
* objects: swap this for a collection-backed `DataSource`.
|
|
13
|
+
*/
|
|
14
|
+
export function createPlannerDataSource() {
|
|
15
|
+
return createMemoryDataSource({
|
|
16
|
+
storage: browserStorage(),
|
|
17
|
+
// Fields the views hide still carry their policy default, e.g. the
|
|
18
|
+
// `contractType` that tells an Order from a PurchaseOrder.
|
|
19
|
+
defaults: (model) => recipeState.apply(model).background,
|
|
20
|
+
// Variants only make sense under a product a form creates, so they start
|
|
21
|
+
// empty, as do Profile types: a form adds the one it needs. Locations, SKUs
|
|
22
|
+
// and stock are sampled together (one SKU per product).
|
|
23
|
+
empty: [VARIANT, PROFILE_TYPE],
|
|
24
|
+
samples: stockSamples(catalogModels),
|
|
25
|
+
// Every sample parent comes with line items: the same parent-to-children
|
|
26
|
+
// lookup the record view uses, so what it shows is what was seeded.
|
|
27
|
+
children: {
|
|
28
|
+
models: catalog.packages.flatMap((p) => p.models),
|
|
29
|
+
links: (id) => childLinks(catalog, recipes, id),
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import type { CatalogModel } from '../catalog/types.ts';
|
|
2
|
+
import { type ChildOf } from './children.ts';
|
|
3
|
+
import { type ModelRecord } from './fakes.ts';
|
|
4
|
+
export type { ModelRecord } from './fakes.ts';
|
|
5
|
+
/**
|
|
6
|
+
* Where the generated views read and write rows. Everything is async so the
|
|
7
|
+
* in-memory fakes here can later be swapped for live s-m-r-t collections
|
|
8
|
+
* without touching a view.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* The id of an earlier write in the same {@link DataSource.apply}, by alias; or,
|
|
12
|
+
* with `field`, that row's value of that field (a Customer's `profileId`).
|
|
13
|
+
*/
|
|
14
|
+
export interface RecordRef {
|
|
15
|
+
ref: string;
|
|
16
|
+
field?: string;
|
|
17
|
+
}
|
|
18
|
+
/** A plain JSON object, e.g. an Address; never a {@link RecordRef}. */
|
|
19
|
+
export type JsonObject = {
|
|
20
|
+
readonly [key: string]: unknown;
|
|
21
|
+
};
|
|
22
|
+
export type WriteValue = string | number | boolean | null | RecordRef | JsonObject;
|
|
23
|
+
export declare function isRecordRef(value: unknown): value is RecordRef;
|
|
24
|
+
/**
|
|
25
|
+
* One step of a multi-model save. `save` updates the row `id`; without an `id`
|
|
26
|
+
* it finds the row whose fields equal `match` (creating it from `match`,
|
|
27
|
+
* `onCreate` and `values` when none does), and without either it creates one. `delete`
|
|
28
|
+
* removes the row `id`, or every row equal to `match`.
|
|
29
|
+
*/
|
|
30
|
+
export type RecordWrite = {
|
|
31
|
+
op: 'save';
|
|
32
|
+
/** Names the written row so a later step can `{ref}` its id. */
|
|
33
|
+
as?: string;
|
|
34
|
+
model: CatalogModel;
|
|
35
|
+
id?: string;
|
|
36
|
+
match?: Record<string, WriteValue>;
|
|
37
|
+
values?: Record<string, WriteValue>;
|
|
38
|
+
/** Extra values applied only when the row is created, not when found. */
|
|
39
|
+
onCreate?: Record<string, WriteValue>;
|
|
40
|
+
} | {
|
|
41
|
+
op: 'delete';
|
|
42
|
+
model: CatalogModel;
|
|
43
|
+
id?: string;
|
|
44
|
+
match?: Record<string, WriteValue>;
|
|
45
|
+
};
|
|
46
|
+
export interface DataSource {
|
|
47
|
+
list(model: CatalogModel): Promise<ModelRecord[]>;
|
|
48
|
+
get(model: CatalogModel, id: string): Promise<ModelRecord | undefined>;
|
|
49
|
+
create(model: CatalogModel, values: Record<string, unknown>): Promise<ModelRecord>;
|
|
50
|
+
update(model: CatalogModel, id: string, values: Record<string, unknown>): Promise<ModelRecord | undefined>;
|
|
51
|
+
delete(model: CatalogModel, id: string): Promise<boolean>;
|
|
52
|
+
/**
|
|
53
|
+
* Related multi-model saves, all or nothing: the steps run in order and if
|
|
54
|
+
* one fails (an unknown `{ref}`, a missing row to update) none is kept.
|
|
55
|
+
* Returns the rows written, by alias.
|
|
56
|
+
*/
|
|
57
|
+
apply(writes: readonly RecordWrite[]): Promise<Record<string, ModelRecord>>;
|
|
58
|
+
/** Forget every row and stored copy; the next read starts from the samples. */
|
|
59
|
+
reset?(): void;
|
|
60
|
+
/**
|
|
61
|
+
* Call `listener` after every `reset`, so a view that already read rows
|
|
62
|
+
* reads them again; returns the way to stop listening.
|
|
63
|
+
*/
|
|
64
|
+
onReset?(listener: () => void): () => void;
|
|
65
|
+
}
|
|
66
|
+
/** Prefix of the localStorage keys rows are kept under, one per model. */
|
|
67
|
+
export declare const DATA_STORAGE_PREFIX = "smrt-planner:data:v3:";
|
|
68
|
+
/** Remove every stored row. Never throws. */
|
|
69
|
+
export declare function clearStoredData(storage: Storage | null | undefined): void;
|
|
70
|
+
export interface MemoryDataSourceOptions {
|
|
71
|
+
/** Seed for the sample data; the same seed gives the same rows. */
|
|
72
|
+
seed?: number;
|
|
73
|
+
/** Rows generated per model on first read. */
|
|
74
|
+
rowsPerModel?: number;
|
|
75
|
+
/**
|
|
76
|
+
* Values every row of a model carries whatever the form shows, e.g. the
|
|
77
|
+
* `contractType` discriminator of a model in a shared table. Read each time
|
|
78
|
+
* a row is read or created, so it follows the current recipe options.
|
|
79
|
+
*/
|
|
80
|
+
defaults?: (model: CatalogModel) => Record<string, unknown>;
|
|
81
|
+
/**
|
|
82
|
+
* Qualified model names that start empty instead of with sample rows:
|
|
83
|
+
* models whose rows only make sense under a parent a form creates (SKUs,
|
|
84
|
+
* stock), where random rows would point at nothing.
|
|
85
|
+
*/
|
|
86
|
+
empty?: readonly string[];
|
|
87
|
+
/**
|
|
88
|
+
* Models whose sample rows are built from other models' rows instead of
|
|
89
|
+
* random fakes (stock levels from the SKUs and locations they count): the
|
|
90
|
+
* parent tables in `from` order, then the rows made from them. The model
|
|
91
|
+
* must not also be a generated child.
|
|
92
|
+
*/
|
|
93
|
+
samples?: Record<string, {
|
|
94
|
+
from: readonly CatalogModel[];
|
|
95
|
+
make: (parents: ModelRecord[][], seed: number) => ModelRecord[];
|
|
96
|
+
}>;
|
|
97
|
+
/**
|
|
98
|
+
* Parent-to-children wiring. With it, every sample parent comes with one to
|
|
99
|
+
* four child rows (line items, allocations, entries) whose foreign key is
|
|
100
|
+
* the parent's id, so an open record's child tables are not empty. `links`
|
|
101
|
+
* is the helper the record view uses (`childLinks`); `models` is what to
|
|
102
|
+
* scan for parents of a child.
|
|
103
|
+
*/
|
|
104
|
+
children?: {
|
|
105
|
+
models: readonly CatalogModel[];
|
|
106
|
+
links: (modelId: string) => ChildOf[];
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Where rows are kept between visits (a model's rows under one versioned
|
|
110
|
+
* key). Without it the rows live in memory only. Edits to a model and the
|
|
111
|
+
* models it owns or belongs to are saved together, so a parent and its
|
|
112
|
+
* line items are never out of step.
|
|
113
|
+
*/
|
|
114
|
+
storage?: Storage | null;
|
|
115
|
+
/** The clock an invoice's overdue status is read against; defaults to the fixed sample clock. */
|
|
116
|
+
now?: () => number;
|
|
117
|
+
}
|
|
118
|
+
/** Deterministic seeded fakes held in memory, lazily per model. */
|
|
119
|
+
export declare function createMemoryDataSource(options?: MemoryDataSourceOptions): DataSource;
|
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
import { fakeChildrenOf, syncTotals } from "./children.js";
|
|
2
|
+
import { allocationInvoiceField, allocationPaymentField, isAllocationModel, isLineModel, PAID_PAYMENT_STATUS, settleInvoice, settleLine, tracksPayments, withTotals, } from "./derived.js";
|
|
3
|
+
import { EPOCH, fakeId, fakeRecords, sampleRowCount, } from "./fakes.js";
|
|
4
|
+
import { fakeAllocations } from "./payments.js";
|
|
5
|
+
export function isRecordRef(value) {
|
|
6
|
+
return (typeof value === 'object' &&
|
|
7
|
+
value !== null &&
|
|
8
|
+
typeof value.ref === 'string');
|
|
9
|
+
}
|
|
10
|
+
/** Prefix of the localStorage keys rows are kept under, one per model. */
|
|
11
|
+
export const DATA_STORAGE_PREFIX = 'smrt-planner:data:v3:';
|
|
12
|
+
const CREATED_KEY = `${DATA_STORAGE_PREFIX}_created`;
|
|
13
|
+
/** Remove every stored row. Never throws. */
|
|
14
|
+
export function clearStoredData(storage) {
|
|
15
|
+
if (!storage)
|
|
16
|
+
return;
|
|
17
|
+
try {
|
|
18
|
+
const keys = [];
|
|
19
|
+
for (let i = 0; i < storage.length; i++) {
|
|
20
|
+
const key = storage.key(i);
|
|
21
|
+
if (key?.startsWith(DATA_STORAGE_PREFIX))
|
|
22
|
+
keys.push(key);
|
|
23
|
+
}
|
|
24
|
+
for (const key of keys)
|
|
25
|
+
storage.removeItem(key);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// Storage may be unavailable; there is nothing to clear then.
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** Deterministic seeded fakes held in memory, lazily per model. */
|
|
32
|
+
export function createMemoryDataSource(options = {}) {
|
|
33
|
+
const seed = options.seed ?? 1;
|
|
34
|
+
const rows = options.rowsPerModel ?? 8;
|
|
35
|
+
const empty = new Set(options.empty ?? []);
|
|
36
|
+
const tables = new Map();
|
|
37
|
+
const resetListeners = new Set();
|
|
38
|
+
const storage = options.storage ?? null;
|
|
39
|
+
const storedKey = (model) => `${DATA_STORAGE_PREFIX}${model.id}`;
|
|
40
|
+
const readStored = (model) => {
|
|
41
|
+
if (!storage)
|
|
42
|
+
return undefined;
|
|
43
|
+
try {
|
|
44
|
+
const raw = storage.getItem(storedKey(model));
|
|
45
|
+
if (raw === null)
|
|
46
|
+
return undefined;
|
|
47
|
+
const parsed = JSON.parse(raw);
|
|
48
|
+
if (Array.isArray(parsed) &&
|
|
49
|
+
parsed.every((r) => typeof r === 'object' && r !== null && typeof r.id === 'string')) {
|
|
50
|
+
return parsed;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// Unreadable: fall back to the samples; the next write replaces it.
|
|
55
|
+
}
|
|
56
|
+
return undefined;
|
|
57
|
+
};
|
|
58
|
+
let created = 0;
|
|
59
|
+
if (storage) {
|
|
60
|
+
try {
|
|
61
|
+
created = Number(storage.getItem(CREATED_KEY)) || 0;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
created = 0;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Parent-to-children wiring, indexed both ways on first use.
|
|
68
|
+
const links = new Map();
|
|
69
|
+
const linksOf = (id) => {
|
|
70
|
+
let found = links.get(id);
|
|
71
|
+
if (!found) {
|
|
72
|
+
found = options.children?.links(id) ?? [];
|
|
73
|
+
links.set(id, found);
|
|
74
|
+
}
|
|
75
|
+
return found;
|
|
76
|
+
};
|
|
77
|
+
let owners;
|
|
78
|
+
// Every parent of a child, before it is narrowed to the one that generates it.
|
|
79
|
+
let allOwners;
|
|
80
|
+
const ownersOf = (id) => {
|
|
81
|
+
if (!owners) {
|
|
82
|
+
owners = new Map();
|
|
83
|
+
for (const parent of options.children?.models ?? []) {
|
|
84
|
+
for (const link of linksOf(parent.id)) {
|
|
85
|
+
const list = owners.get(link.model.id) ?? [];
|
|
86
|
+
list.push({ parent, fk: link.fk });
|
|
87
|
+
owners.set(link.model.id, list);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// A child pointing at several kinds of parent (a JournalEntry at a
|
|
91
|
+
// Journal and an Account) is generated under one key only: the one its
|
|
92
|
+
// name starts with, else the first. Its other keys already hold ids of
|
|
93
|
+
// real sample rows.
|
|
94
|
+
allOwners = new Map(owners);
|
|
95
|
+
for (const [id, list] of owners) {
|
|
96
|
+
const name = id.slice(id.lastIndexOf(':') + 1).toLowerCase();
|
|
97
|
+
const main = list.find((o) => name.startsWith(o.fk.replace(/Id$/, '').toLowerCase()))?.fk ?? list[0]?.fk;
|
|
98
|
+
owners.set(id, list.filter((o) => o.fk === main));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return owners.get(id) ?? [];
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* A payment applied to an invoice has two parents; its rows are generated
|
|
105
|
+
* once, from both, so they add up (see `fakeAllocations`).
|
|
106
|
+
*/
|
|
107
|
+
const allocationSpecOf = (model) => {
|
|
108
|
+
if (!isAllocationModel(model))
|
|
109
|
+
return undefined;
|
|
110
|
+
ownersOf(model.id);
|
|
111
|
+
const parents = allOwners?.get(model.id) ?? [];
|
|
112
|
+
const paymentFk = allocationPaymentField(model)?.name;
|
|
113
|
+
const invoiceFk = allocationInvoiceField(model)?.name;
|
|
114
|
+
const payment = parents.find((o) => o.fk === paymentFk)?.parent;
|
|
115
|
+
const invoice = parents.find((o) => o.fk === invoiceFk)?.parent;
|
|
116
|
+
return payment && invoice && paymentFk && invoiceFk
|
|
117
|
+
? { model, paymentFk, invoiceFk, payment, invoice }
|
|
118
|
+
: undefined;
|
|
119
|
+
};
|
|
120
|
+
/** The invoice row with its payment state taken from its allocations. */
|
|
121
|
+
const settleInvoiceRow = (invoiceModel, row) => {
|
|
122
|
+
if (!tracksPayments(invoiceModel))
|
|
123
|
+
return row;
|
|
124
|
+
const link = linksOf(invoiceModel.id).find((l) => isAllocationModel(l.model));
|
|
125
|
+
const spec = link && allocationSpecOf(link.model);
|
|
126
|
+
if (!link || !spec)
|
|
127
|
+
return row;
|
|
128
|
+
const payments = new Map(table(spec.payment).map((p) => [p.id, p]));
|
|
129
|
+
const counted = table(link.model)
|
|
130
|
+
.filter((a) => a[link.fk] === row.id &&
|
|
131
|
+
payments.get(String(a[spec.paymentFk]))?.status ===
|
|
132
|
+
PAID_PAYMENT_STATUS)
|
|
133
|
+
.map((a) => ({
|
|
134
|
+
amount: Number(a.amount ?? 0),
|
|
135
|
+
at: String(a.allocatedAt ?? ''),
|
|
136
|
+
}));
|
|
137
|
+
const settled = settleInvoice(row, counted, (options.now ?? (() => EPOCH))());
|
|
138
|
+
const next = {
|
|
139
|
+
...row,
|
|
140
|
+
amountPaid: settled.amountPaid,
|
|
141
|
+
status: settled.status,
|
|
142
|
+
};
|
|
143
|
+
if (invoiceModel.fields.some((f) => f.name === 'paidDate')) {
|
|
144
|
+
next.paidDate = settled.paidDate;
|
|
145
|
+
}
|
|
146
|
+
return next;
|
|
147
|
+
};
|
|
148
|
+
const resettleInvoice = (invoiceModel, id) => {
|
|
149
|
+
const list = table(invoiceModel);
|
|
150
|
+
const index = list.findIndex((r) => r.id === id);
|
|
151
|
+
if (index >= 0) {
|
|
152
|
+
list[index] = settleInvoiceRow(invoiceModel, list[index]);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
const table = (model) => {
|
|
156
|
+
const existing = tables.get(model.id);
|
|
157
|
+
if (existing)
|
|
158
|
+
return existing;
|
|
159
|
+
const stored = readStored(model);
|
|
160
|
+
if (stored) {
|
|
161
|
+
tables.set(model.id, stored);
|
|
162
|
+
for (const link of linksOf(model.id))
|
|
163
|
+
table(link.model);
|
|
164
|
+
return stored;
|
|
165
|
+
}
|
|
166
|
+
const sample = empty.has(model.id)
|
|
167
|
+
? undefined
|
|
168
|
+
: options.samples?.[model.id];
|
|
169
|
+
if (sample) {
|
|
170
|
+
const made = [];
|
|
171
|
+
tables.set(model.id, made);
|
|
172
|
+
made.push(...sample.make(sample.from.map(table), seed));
|
|
173
|
+
return made;
|
|
174
|
+
}
|
|
175
|
+
const allocation = allocationSpecOf(model);
|
|
176
|
+
const owned = allocation ? [] : ownersOf(model.id);
|
|
177
|
+
// A child's rows come from its parents, never from random fakes.
|
|
178
|
+
const made = empty.has(model.id) || owned.length || allocation
|
|
179
|
+
? []
|
|
180
|
+
: fakeRecords(model, sampleRowCount(model.id, rows), seed);
|
|
181
|
+
// Registered before the other side is built so each finds this table.
|
|
182
|
+
tables.set(model.id, made);
|
|
183
|
+
for (const link of linksOf(model.id))
|
|
184
|
+
table(link.model);
|
|
185
|
+
if (allocation && !empty.has(model.id)) {
|
|
186
|
+
// Totals first: an allocation can be no more than its invoice owes.
|
|
187
|
+
for (const link of linksOf(allocation.invoice.id)) {
|
|
188
|
+
if (isLineModel(link.model))
|
|
189
|
+
table(link.model);
|
|
190
|
+
}
|
|
191
|
+
const invoices = table(allocation.invoice);
|
|
192
|
+
made.push(...fakeAllocations(allocation, table(allocation.payment), invoices, seed));
|
|
193
|
+
invoices.forEach((row, i) => {
|
|
194
|
+
invoices[i] = settleInvoiceRow(allocation.invoice, row);
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
if (!empty.has(model.id)) {
|
|
198
|
+
for (const { parent, fk } of owned) {
|
|
199
|
+
for (const row of table(parent)) {
|
|
200
|
+
const items = fakeChildrenOf(model, fk, row, seed);
|
|
201
|
+
made.push(...items);
|
|
202
|
+
syncTotals(row, parent, items);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return made;
|
|
207
|
+
};
|
|
208
|
+
/** Save the model and the tables it is built together with. */
|
|
209
|
+
const persist = (model) => {
|
|
210
|
+
if (!storage)
|
|
211
|
+
return;
|
|
212
|
+
// A payment and the invoice it pays are saved together with their
|
|
213
|
+
// allocations: the sample rows of each depend on the others.
|
|
214
|
+
const pair = (m) => {
|
|
215
|
+
const spec = allocationSpecOf(m);
|
|
216
|
+
return spec ? [spec.payment, spec.invoice] : [];
|
|
217
|
+
};
|
|
218
|
+
const family = [
|
|
219
|
+
model,
|
|
220
|
+
...linksOf(model.id).map((l) => l.model),
|
|
221
|
+
...ownersOf(model.id).map((o) => o.parent),
|
|
222
|
+
...pair(model),
|
|
223
|
+
...linksOf(model.id).flatMap((l) => pair(l.model)),
|
|
224
|
+
];
|
|
225
|
+
try {
|
|
226
|
+
for (const member of family) {
|
|
227
|
+
const rows = tables.get(member.id);
|
|
228
|
+
if (rows)
|
|
229
|
+
storage.setItem(storedKey(member), JSON.stringify(rows));
|
|
230
|
+
}
|
|
231
|
+
storage.setItem(CREATED_KEY, String(created));
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
// Quota or private mode: the rows stay in memory for this visit.
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
/** A parent's line items, by its id. */
|
|
238
|
+
const lineLink = (parent) => linksOf(parent.id).find((l) => isLineModel(l.model));
|
|
239
|
+
/** Recompute a parent's totals from its lines (they are never typed in). */
|
|
240
|
+
const resync = (parent, parentId) => {
|
|
241
|
+
const link = lineLink(parent);
|
|
242
|
+
if (!link)
|
|
243
|
+
return;
|
|
244
|
+
const list = table(parent);
|
|
245
|
+
const index = list.findIndex((r) => r.id === parentId);
|
|
246
|
+
if (index < 0)
|
|
247
|
+
return;
|
|
248
|
+
const lines = table(link.model).filter((r) => r[link.fk] === parentId);
|
|
249
|
+
list[index] = withTotals(parent, list[index], lines);
|
|
250
|
+
};
|
|
251
|
+
/** Settle a written row, then the parents whose totals depend on it. */
|
|
252
|
+
const settle = (model, record) => {
|
|
253
|
+
let settled = record;
|
|
254
|
+
if (isLineModel(model)) {
|
|
255
|
+
settled = settleLine(record);
|
|
256
|
+
const list = table(model);
|
|
257
|
+
const index = list.findIndex((r) => r.id === record.id);
|
|
258
|
+
if (index >= 0)
|
|
259
|
+
list[index] = settled;
|
|
260
|
+
}
|
|
261
|
+
if (lineLink(model)) {
|
|
262
|
+
resync(model, record.id);
|
|
263
|
+
settled = table(model).find((r) => r.id === record.id) ?? settled;
|
|
264
|
+
}
|
|
265
|
+
for (const { parent, fk } of ownersOf(model.id)) {
|
|
266
|
+
if (isLineModel(model))
|
|
267
|
+
resync(parent, record[fk]);
|
|
268
|
+
}
|
|
269
|
+
// What an invoice has paid follows its allocations and their payments.
|
|
270
|
+
if (tracksPayments(model)) {
|
|
271
|
+
resettleInvoice(model, record.id);
|
|
272
|
+
settled = table(model).find((r) => r.id === record.id) ?? settled;
|
|
273
|
+
}
|
|
274
|
+
const spec = allocationSpecOf(model);
|
|
275
|
+
if (spec)
|
|
276
|
+
resettleInvoice(spec.invoice, record[spec.invoiceFk]);
|
|
277
|
+
for (const link of linksOf(model.id)) {
|
|
278
|
+
const child = allocationSpecOf(link.model);
|
|
279
|
+
if (!child || child.payment.id !== model.id)
|
|
280
|
+
continue;
|
|
281
|
+
for (const row of table(link.model)) {
|
|
282
|
+
if (row[child.paymentFk] === record.id) {
|
|
283
|
+
resettleInvoice(child.invoice, row[child.invoiceFk]);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return settled;
|
|
288
|
+
};
|
|
289
|
+
const present = (model, record) => ({
|
|
290
|
+
...record,
|
|
291
|
+
...(options.defaults?.(model) ?? {}),
|
|
292
|
+
});
|
|
293
|
+
const nextId = (model) => fakeId(`${model.id}:new:${seed}:${created++}`);
|
|
294
|
+
const matches = (record, match) => Object.entries(match).every(([key, value]) => record[key] === value);
|
|
295
|
+
return {
|
|
296
|
+
async list(model) {
|
|
297
|
+
return table(model).map((r) => present(model, r));
|
|
298
|
+
},
|
|
299
|
+
async get(model, id) {
|
|
300
|
+
const found = table(model).find((r) => r.id === id);
|
|
301
|
+
return found ? present(model, found) : undefined;
|
|
302
|
+
},
|
|
303
|
+
async create(model, values) {
|
|
304
|
+
const record = {
|
|
305
|
+
...(options.defaults?.(model) ?? {}),
|
|
306
|
+
...values,
|
|
307
|
+
id: nextId(model),
|
|
308
|
+
};
|
|
309
|
+
table(model).push(record);
|
|
310
|
+
const settled = settle(model, record);
|
|
311
|
+
persist(model);
|
|
312
|
+
return { ...settled };
|
|
313
|
+
},
|
|
314
|
+
async update(model, id, values) {
|
|
315
|
+
const list = table(model);
|
|
316
|
+
const index = list.findIndex((r) => r.id === id);
|
|
317
|
+
if (index < 0)
|
|
318
|
+
return undefined;
|
|
319
|
+
const next = { ...list[index], ...values, id };
|
|
320
|
+
list[index] = next;
|
|
321
|
+
const settled = settle(model, next);
|
|
322
|
+
persist(model);
|
|
323
|
+
return { ...settled };
|
|
324
|
+
},
|
|
325
|
+
async delete(model, id) {
|
|
326
|
+
const list = table(model);
|
|
327
|
+
const index = list.findIndex((r) => r.id === id);
|
|
328
|
+
if (index < 0)
|
|
329
|
+
return false;
|
|
330
|
+
const [gone] = list.splice(index, 1);
|
|
331
|
+
const spec = allocationSpecOf(model);
|
|
332
|
+
if (spec && gone)
|
|
333
|
+
resettleInvoice(spec.invoice, gone[spec.invoiceFk]);
|
|
334
|
+
for (const { parent, fk } of ownersOf(model.id)) {
|
|
335
|
+
if (isLineModel(model) && gone)
|
|
336
|
+
resync(parent, gone[fk]);
|
|
337
|
+
}
|
|
338
|
+
persist(model);
|
|
339
|
+
return true;
|
|
340
|
+
},
|
|
341
|
+
reset() {
|
|
342
|
+
tables.clear();
|
|
343
|
+
created = 0;
|
|
344
|
+
clearStoredData(storage);
|
|
345
|
+
for (const listener of [...resetListeners])
|
|
346
|
+
listener();
|
|
347
|
+
},
|
|
348
|
+
onReset(listener) {
|
|
349
|
+
resetListeners.add(listener);
|
|
350
|
+
return () => {
|
|
351
|
+
resetListeners.delete(listener);
|
|
352
|
+
};
|
|
353
|
+
},
|
|
354
|
+
async apply(writes) {
|
|
355
|
+
// Snapshot every table a step touches; restore them all if one throws.
|
|
356
|
+
const snapshots = new Map();
|
|
357
|
+
const counter = created;
|
|
358
|
+
const touched = new Map();
|
|
359
|
+
const touch = (model) => {
|
|
360
|
+
touched.set(model.id, model);
|
|
361
|
+
const rows = table(model);
|
|
362
|
+
if (!snapshots.has(model.id)) {
|
|
363
|
+
snapshots.set(model.id, rows.map((r) => ({ ...r })));
|
|
364
|
+
}
|
|
365
|
+
return rows;
|
|
366
|
+
};
|
|
367
|
+
const written = {};
|
|
368
|
+
const resolve = (values) => Object.fromEntries(Object.entries(values ?? {}).map(([key, value]) => {
|
|
369
|
+
if (!isRecordRef(value))
|
|
370
|
+
return [key, value];
|
|
371
|
+
const target = written[value.ref];
|
|
372
|
+
if (!target)
|
|
373
|
+
throw new Error(`Unknown record reference ${value.ref}`);
|
|
374
|
+
return [key, value.field ? target[value.field] : target.id];
|
|
375
|
+
}));
|
|
376
|
+
try {
|
|
377
|
+
for (const write of writes) {
|
|
378
|
+
const list = touch(write.model);
|
|
379
|
+
const match = resolve(write.match);
|
|
380
|
+
if (write.op === 'delete') {
|
|
381
|
+
const doomed = list.filter((r) => write.id !== undefined ? r.id === write.id : matches(r, match));
|
|
382
|
+
if (write.id === undefined && Object.keys(match).length === 0) {
|
|
383
|
+
throw new Error('A delete needs an id or a match');
|
|
384
|
+
}
|
|
385
|
+
for (const record of doomed) {
|
|
386
|
+
list.splice(list.indexOf(record), 1);
|
|
387
|
+
}
|
|
388
|
+
continue;
|
|
389
|
+
}
|
|
390
|
+
const values = resolve(write.values);
|
|
391
|
+
let index = -1;
|
|
392
|
+
if (write.id !== undefined) {
|
|
393
|
+
index = list.findIndex((r) => r.id === write.id);
|
|
394
|
+
if (index < 0) {
|
|
395
|
+
throw new Error(`No ${write.model.name} with id ${write.id}`);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
else if (Object.keys(match).length > 0) {
|
|
399
|
+
index = list.findIndex((r) => matches(r, match));
|
|
400
|
+
}
|
|
401
|
+
let record;
|
|
402
|
+
if (index >= 0) {
|
|
403
|
+
const current = list[index];
|
|
404
|
+
record = { ...current, ...values, id: current.id };
|
|
405
|
+
list[index] = record;
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
record = {
|
|
409
|
+
...(options.defaults?.(write.model) ?? {}),
|
|
410
|
+
...match,
|
|
411
|
+
...resolve(write.onCreate),
|
|
412
|
+
...values,
|
|
413
|
+
id: nextId(write.model),
|
|
414
|
+
};
|
|
415
|
+
list.push(record);
|
|
416
|
+
}
|
|
417
|
+
if (write.as)
|
|
418
|
+
written[write.as] = { ...record };
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
catch (error) {
|
|
422
|
+
for (const [id, rows] of snapshots)
|
|
423
|
+
tables.set(id, rows);
|
|
424
|
+
created = counter;
|
|
425
|
+
throw error;
|
|
426
|
+
}
|
|
427
|
+
for (const model of touched.values())
|
|
428
|
+
persist(model);
|
|
429
|
+
return written;
|
|
430
|
+
},
|
|
431
|
+
};
|
|
432
|
+
}
|