@dyrected/core 2.22.0 → 2.24.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/{app-BBHBP-6V.d.cts → app-BpQPL2hY.d.cts} +155 -8
- package/dist/{app-BBHBP-6V.d.ts → app-BpQPL2hY.d.ts} +155 -8
- package/dist/index.cjs +286 -9
- package/dist/index.d.cts +46 -6
- package/dist/index.d.ts +46 -6
- package/dist/index.js +280 -9
- package/dist/server.cjs +397 -93
- package/dist/server.d.cts +2 -2
- package/dist/server.d.ts +2 -2
- package/dist/server.js +397 -93
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as Field, B as Block, C as CollectionConfig, D as DyrectedConfig, A as AdminAuthConfig, P as PublicAdminAuthConfig, G as GlobalConfig, a as DeclarativeHookExpression, W as WorkflowConfig, b as AuthenticatedUser, c as WorkflowTransition, L as LifecycleEventName, d as LifecycleEvent, e as DatabaseAdapter, f as BaseDocument, H as HookRequestContext, T as TaskRunResult, g as TaskConfig, h as DetailActionOptions, i as DetailAction, j as DetailComputedOptions, k as ComputedHandler, l as DetailComputed, m as DetailCustomOptions, n as DetailCustom, o as DetailDividerOptions, p as DetailDivider, q as DisplayFieldOptions, r as DetailField, s as DetailItem, t as DetailGridOptions, u as DetailGrid, v as DetailRepeatOptions, w as DetailRepeat, x as DetailSectionOptions, y as DetailSection, z as DetailTabOptions, E as DetailTab, I as DetailTabsOptions, J as DetailTabs, K as DetailTextOptions, M as DetailText, N as DetailSchema, O as DyrectedContext, Q as AIConfig, R as AIPIIConfig, S as IdStrategy, U as CompiledNavTree, V as CompiledNavItem, X as UserNavigationPreferences, Y as DefineWorkspaceOptions, Z as ViewConfig, _ as DateTimeField, $ as RelationshipField, a0 as SelectField, a1 as ArrayField, a2 as FieldType, a3 as BooleanField, a4 as AuthConfig, a5 as AccessPolicyResolver, a6 as DateField, a7 as TextField, a8 as EmailField, a9 as IconField, aa as ImageField, ab as JoinField, ac as JsonField, ad as MoneyField, ae as MultiSelectField, af as NumberField, ag as ObjectField, ah as RadioField, ai as RichTextField, aj as RowField, ak as TextareaField, al as TimeField, am as UrlField } from './app-
|
|
2
|
-
export { an as AIAction, ao as AIActionStatus, ap as AIActionType, aq as AIAuditActionType, ar as AIAuditRecord, as as AIChunk, at as AIMessage, au as AIPIIPattern, av as AIRateLimitResult, aw as AIRateLimitStore, ax as AIThread, ay as AIToolContext, az as AIToolDefinition, aA as AI_ACTIONS_COLLECTION, aB as AI_AUDIT_COLLECTION, aC as AI_CHUNKS_COLLECTION, aD as AI_MESSAGES_COLLECTION, aE as AI_THREADS_COLLECTION, aF as AccessConfig, aG as AccessFunction, aH as AccessFunctionArgs, aI as AccessResult, aJ as AccessRule, aK as ActionConfig, aL as ActionConfigBase, aM as ActionConfigWithHandler, aN as ActionConfigWithMutation, aO as ActionContext, aP as ActionType, aQ as AdminAuthAccessResolution, aR as AdminAuthClaimMapping, aS as AdminAuthMember, aT as AdminAuthProvider, aU as AdminAuthProviderMembersConfig, aV as AdminAuthProvisioningMode, aW as AdminAuthResolveAccessArgs, aX as AdminAuthResolvedIdentity, aY as AdminConfig, aZ as AdminDashboardComponentSlots, a_ as AdminIconName, a$ as AggregateArgs, b0 as AggregateCastType, b1 as AggregateCollectionResult, b2 as AggregateInput, b3 as AggregateOperation, b4 as AggregateResult, b5 as AppTrashConfig, b6 as BaseAdminAuthProvider, b7 as BaseFieldAdmin, b8 as BlockVariant, b9 as BlocksField, ba as BooleanFieldAdmin, bb as BooleanFormat, bc as CURRENT_NAV_PREFERENCES_VERSION, bd as
|
|
1
|
+
import { F as Field, B as Block, C as CollectionConfig, D as DyrectedConfig, A as AdminAuthConfig, P as PublicAdminAuthConfig, G as GlobalConfig, a as DeclarativeHookExpression, W as WorkflowConfig, b as AuthenticatedUser, c as WorkflowTransition, L as LifecycleEventName, d as LifecycleEvent, e as DatabaseAdapter, f as BaseDocument, H as HookRequestContext, T as TaskRunResult, g as TaskConfig, h as DetailActionOptions, i as DetailAction, j as DetailComputedOptions, k as ComputedHandler, l as DetailComputed, m as DetailCustomOptions, n as DetailCustom, o as DetailDividerOptions, p as DetailDivider, q as DisplayFieldOptions, r as DetailField, s as DetailItem, t as DetailGridOptions, u as DetailGrid, v as DetailRepeatOptions, w as DetailRepeat, x as DetailSectionOptions, y as DetailSection, z as DetailTabOptions, E as DetailTab, I as DetailTabsOptions, J as DetailTabs, K as DetailTextOptions, M as DetailText, N as DetailSchema, O as DyrectedContext, Q as AIConfig, R as AIPIIConfig, S as IdStrategy, U as CompiledNavTree, V as CompiledNavItem, X as UserNavigationPreferences, Y as DefineWorkspaceOptions, Z as ViewConfig, _ as DateTimeField, $ as RelationshipField, a0 as SelectField, a1 as ArrayField, a2 as FieldType, a3 as BooleanField, a4 as AuthConfig, a5 as AccessPolicyResolver, a6 as DateField, a7 as TextField, a8 as EmailField, a9 as IconField, aa as ImageField, ab as JoinField, ac as JsonField, ad as MoneyField, ae as MultiSelectField, af as NumberField, ag as ObjectField, ah as RadioField, ai as RichTextField, aj as RowField, ak as TextareaField, al as TimeField, am as UrlField } from './app-BpQPL2hY.js';
|
|
2
|
+
export { an as AIAction, ao as AIActionStatus, ap as AIActionType, aq as AIAuditActionType, ar as AIAuditRecord, as as AIChunk, at as AIMessage, au as AIPIIPattern, av as AIRateLimitResult, aw as AIRateLimitStore, ax as AIThread, ay as AIToolContext, az as AIToolDefinition, aA as AI_ACTIONS_COLLECTION, aB as AI_AUDIT_COLLECTION, aC as AI_CHUNKS_COLLECTION, aD as AI_MESSAGES_COLLECTION, aE as AI_THREADS_COLLECTION, aF as AccessConfig, aG as AccessFunction, aH as AccessFunctionArgs, aI as AccessResult, aJ as AccessRule, aK as ActionConfig, aL as ActionConfigBase, aM as ActionConfigWithHandler, aN as ActionConfigWithMutation, aO as ActionContext, aP as ActionType, aQ as AdminAuthAccessResolution, aR as AdminAuthClaimMapping, aS as AdminAuthMember, aT as AdminAuthProvider, aU as AdminAuthProviderMembersConfig, aV as AdminAuthProvisioningMode, aW as AdminAuthResolveAccessArgs, aX as AdminAuthResolvedIdentity, aY as AdminConfig, aZ as AdminDashboardComponentSlots, a_ as AdminIconName, a$ as AggregateArgs, b0 as AggregateCastType, b1 as AggregateCollectionResult, b2 as AggregateInput, b3 as AggregateOperation, b4 as AggregateResult, b5 as AppTrashConfig, b6 as BaseAdminAuthProvider, b7 as BaseFieldAdmin, b8 as BlockVariant, b9 as BlocksField, ba as BooleanFieldAdmin, bb as BooleanFormat, bc as CURRENT_NAV_PREFERENCES_VERSION, bd as CUSTOM_VIEW_FETCH_ALL_LIMIT, be as CalendarViewConfig, bf as CardsViewConfig, bg as CharacterLimitFieldAdmin, bh as CharacterLimitFieldConfig, bi as CollectionAfterChangeHook, bj as CollectionAfterDeleteHook, bk as CollectionAfterReadHook, bl as CollectionAfterReadHookEntry, bm as CollectionAfterRestoreHook, bn as CollectionAfterTransitionHook, bo as CollectionAfterTrashHook, bp as CollectionBeforeChangeHook, bq as CollectionBeforeChangeHookEntry, br as CollectionBeforeCommitHook, bs as CollectionBeforeDeleteHook, bt as CollectionBeforeReadHook, bu as CollectionBeforeReadHookEntry, bv as CollectionBeforeRestoreHook, bw as CollectionBeforeTransitionHook, bx as CollectionBeforeTrashHook, by as CollectionEmailConfig, bz as CollectionIndex, bA as CollectionListComponentSlots, bB as CollectionRAGConfig, bC as CollectionSchemaResult, bD as CollectionSummaryResult, bE as CollectionViewComponentSlots, bF as CompiledNavGroup, bG as CountOperation, bH as CustomAdminAuthProvider, bI as CustomViewConfig, bJ as CustomViewDataConfig, bK as DEFAULT_USER_NAV_PREFERENCES, bL as DateFieldAdmin, bM as DateFormat, bN as DefaultValueContext, bO as DefineActionOptions, bP as DefineCalendarViewOptions, bQ as DefineCardsViewOptions, bR as DefineCustomViewOptions, bS as DefineGanttViewOptions, bT as DefineKanbanViewOptions, bU as DefinePageInput, bV as DefineTableViewOptions, bW as DefineViewBaseOptions, bX as DefineViewOptions, bY as DetailSpan, bZ as DisplayTone, b_ as DisplayVariant, b$ as DistinctCountOperation, c0 as DistinctValuesOperation, c1 as DocumentFormComponentSlots, c2 as DynamicOptionItem, c3 as DynamicOptionsConfig, c4 as DynamicOptionsResolver, c5 as DynamicOptionsResolverArgs, c6 as DyrectedAIContext, c7 as DyrectedLoggerConfig, c8 as DyrectedObservabilityConfig, c9 as EmailFieldAdmin, ca as EmailTemplateArgs, cb as EmailTemplateResult, cc as FORM_SHELLS, cd as FieldAdminHooks, ce as FieldAdminOnChangeHook, cf as FieldAdminOnChangeHookArgs, cg as FieldAdminOptionsHook, ch as FieldAdminOptionsHookArgs, ci as FieldAdminOptionsHookResult, cj as FieldAfterReadHook, ck as FieldAfterReadHookArgs, cl as FieldBase, cm as FieldBeforeChangeHook, cn as FieldBeforeChangeHookArgs, co as FieldHook, cp as FieldHooks, cq as FileData, cr as FormShell, cs as GanttViewConfig, ct as GetDocumentResult, cu as GlobalAfterChangeHook, cv as GlobalAfterReadHook, cw as GlobalAfterReadHookEntry, cx as GlobalBeforeChangeHook, cy as GlobalBeforeChangeHookEntry, cz as GlobalBeforeReadHook, cA as GlobalBeforeReadHookEntry, cB as GlobalFormComponentSlots, cC as GlobalRAGConfig, cD as GlobalSchemaResult, cE as GlobalSummaryResult, cF as HeadingLevel, cG as HookFunction, cH as IconFieldAdmin, cI as ImageService, cJ as ImageTransformOptions, cK as InferAggregateResult, cL as JoinFieldAdmin, cM as JsonFieldAdmin, cN as JsonFormat, cO as KanbanViewConfig, cP as LIFECYCLE_EVENT_NAMES, cQ as LifecycleEventHandler, cR as LinkFormat, cS as MetricColor, cT as MoneyFieldAdmin, cU as MoneyFieldConfig, cV as MultiSelectFieldAdmin, cW as NamedAccessPolicy, cX as NavBadgeConfig, cY as NavGroup, cZ as NumberFieldAdmin, c_ as NumberFormat, c$ as NumberLimitFieldAdmin, d0 as NumberLimitFieldConfig, d1 as NumericOperation, d2 as NumericUpdateOperator, d3 as OIDCAdminAuthProvider, d4 as OptionFormat, d5 as OutboundEmail, d6 as PageAction, d7 as PageBreadcrumbItem, d8 as PageConfig, d9 as PaginatedResult, da as PinnedNavItemRef, db as PublicAdminAuthProvider, dc as QueryCollectionResult, dd as RAGSearchResult, de as RadioFieldAdmin, df as RateLimitConfig, dg as ReadonlyDatabaseAdapter, dh as RichTextFeature, di as RichTextFieldConfig, dj as SelectFieldAdmin, dk as SqlWhereResult, dl as StorageAdapter, dm as TableViewConfig, dn as TaskContext, dp as TaskLogger, dq as TaskRunStatus, dr as TextFieldAdmin, ds as TextFormat, dt as TextareaFieldAdmin, du as TrashConfig, dv as TrustProxyConfig, dw as TypedField, dx as UploadConfig, dy as UrlFieldAdmin, dz as UrlLinkValue, dA as ViewActionFeatures, dB as ViewComponentSlots, dC as ViewConfigBase, dD as ViewLayout, dE as ViewMetric, dF as ViewMetricGroupBy, dG as ViewMetricGroupByConfig, dH as ViewMetricTrendConfig, dI as ViewSubMetric, dJ as WhereClause, dK as WhereOperator, dL as WhereOperatorName, dM as WordLimitFieldAdmin, dN as WordLimitFieldConfig, dO as WorkflowMetadata, dP as WorkflowOnTransitionContext, dQ as WorkflowOnTransitionHook, dR as WorkflowRole, dS as WorkflowState, dT as WorkflowTransitionContext, dU as coerceBooleanWhere, dV as defineAction, dW as defineCalendarView, dX as defineCardsView, dY as defineCustomView, dZ as defineGanttView, d_ as defineKanbanView, d$ as definePage, e0 as defineTableView, e1 as defineView, e2 as defineWorkspace, e3 as isAICollection, e4 as parseMongoWhere, e5 as parseSqlWhere } from './app-BpQPL2hY.js';
|
|
3
3
|
import jexl from 'jexl';
|
|
4
4
|
import { Context } from 'hono';
|
|
5
5
|
export { z } from 'zod';
|
|
@@ -280,7 +280,7 @@ interface DeclarativePreviewValidationIssue {
|
|
|
280
280
|
}
|
|
281
281
|
interface ConfigDiagnostic {
|
|
282
282
|
severity: "error" | "warning";
|
|
283
|
-
source: "declarativeHook" | "declarativeAccess" | "adminCondition" | "previewUrl";
|
|
283
|
+
source: "declarativeHook" | "declarativeAccess" | "adminCondition" | "previewUrl" | "adminComponents";
|
|
284
284
|
path: string;
|
|
285
285
|
surface: string;
|
|
286
286
|
message: string;
|
|
@@ -292,7 +292,7 @@ type DiagnosticFormatOptions = {
|
|
|
292
292
|
type DeclarativeValidationConfig = {
|
|
293
293
|
blocks?: Array<Pick<Block, "fields"> & Partial<Pick<Block, "slug">>>;
|
|
294
294
|
collections: Array<Pick<CollectionConfig, "fields" | "hooks" | "access" | "admin"> & Partial<Pick<CollectionConfig, "slug">>>;
|
|
295
|
-
globals?: Array<Pick<GlobalConfig, "fields" | "hooks" | "access"> & Partial<Pick<GlobalConfig, "slug">>>;
|
|
295
|
+
globals?: Array<Pick<GlobalConfig, "fields" | "hooks" | "access" | "admin"> & Partial<Pick<GlobalConfig, "slug">>>;
|
|
296
296
|
accessPolicies?: Record<string, unknown>;
|
|
297
297
|
};
|
|
298
298
|
declare function validateDeclarativeHookExpression(expression: string, surface: DeclarativeHookSurface, path: string): DeclarativeHookValidationIssue[];
|
|
@@ -305,6 +305,14 @@ declare function collectDeclarativeHookValidationIssues(config: DeclarativeValid
|
|
|
305
305
|
declare function collectDeclarativeAccessValidationIssues(config: DeclarativeValidationConfig): DeclarativeAccessValidationIssue[];
|
|
306
306
|
declare function collectAdminConditionValidationIssues(config: DeclarativeValidationConfig): DeclarativeAdminValidationIssue[];
|
|
307
307
|
declare function collectPreviewUrlValidationIssues(config: DeclarativeValidationConfig): DeclarativePreviewValidationIssue[];
|
|
308
|
+
interface AdminComponentsValidationIssue {
|
|
309
|
+
path: string;
|
|
310
|
+
surface: "collection.admin.components" | "global.admin.components";
|
|
311
|
+
message: string;
|
|
312
|
+
expression: string;
|
|
313
|
+
}
|
|
314
|
+
/** Flags malformed `createForm`, `editForm`, `form` and `formShell` settings. */
|
|
315
|
+
declare function collectAdminComponentsValidationIssues(config: DeclarativeValidationConfig): AdminComponentsValidationIssue[];
|
|
308
316
|
declare function assertValidAdminConditionsInConfig(config: DeclarativeValidationConfig, source?: string): void;
|
|
309
317
|
declare function assertValidPreviewUrlsInConfig(config: DeclarativeValidationConfig, source?: string): void;
|
|
310
318
|
declare function collectConfigDiagnostics(config: DeclarativeValidationConfig): ConfigDiagnostic[];
|
|
@@ -318,6 +326,38 @@ declare function isConfigValidationError(error: unknown): error is ConfigValidat
|
|
|
318
326
|
declare function assertValidDeclarativeHooksInConfig(config: DeclarativeValidationConfig, source?: string): void;
|
|
319
327
|
declare function assertValidDeclarativeAccessInConfig(config: DeclarativeValidationConfig, source?: string): void;
|
|
320
328
|
|
|
329
|
+
/**
|
|
330
|
+
* Component keys a schema references, grouped by the `AdminComponents`
|
|
331
|
+
* registry that must supply them.
|
|
332
|
+
*
|
|
333
|
+
* Registration happens in the host app's admin bundle, so this scan is the
|
|
334
|
+
* single source of truth for both type generation (CLI) and the admin's
|
|
335
|
+
* unused-registration warning.
|
|
336
|
+
*/
|
|
337
|
+
interface ReferencedComponentKeys {
|
|
338
|
+
/** `field.admin.component` keys, resolved against `components.fields`. */
|
|
339
|
+
fields: Set<string>;
|
|
340
|
+
/** `admin.components.before/afterDashboard` keys. */
|
|
341
|
+
dashboard: Set<string>;
|
|
342
|
+
/** `collection.admin.components` list slots. */
|
|
343
|
+
collectionList: Set<string>;
|
|
344
|
+
/** Operational view slots (`collectionView` and per-view `components`). */
|
|
345
|
+
collectionView: Set<string>;
|
|
346
|
+
/** `createForm`, `editForm` and `form` keys on collections, and `editForm`/`form` on globals. */
|
|
347
|
+
forms: Set<string>;
|
|
348
|
+
/** `component` of views with `layout: "custom"`. */
|
|
349
|
+
viewLayouts: Set<string>;
|
|
350
|
+
/** `admin.pages[].component` keys. */
|
|
351
|
+
pages: Set<string>;
|
|
352
|
+
/** `displayCustom(name)` keys used in Detail View layouts. */
|
|
353
|
+
customComponents: Set<string>;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Collects every component key a schema (or a `DyrectedConfig`) references.
|
|
357
|
+
* Tolerant of partial or unknown shapes: anything unrecognised is skipped.
|
|
358
|
+
*/
|
|
359
|
+
declare function collectReferencedComponentKeys(schema: unknown): ReferencedComponentKeys;
|
|
360
|
+
|
|
321
361
|
/**
|
|
322
362
|
* Transforms a string into a clean, URL-safe slug.
|
|
323
363
|
* Strips accents, lowercases, removes non-alphanumeric characters, and hyphens whitespace.
|
|
@@ -1522,7 +1562,7 @@ declare function reconcileNavigation(baseTree: CompiledNavTree | null | undefine
|
|
|
1522
1562
|
*/
|
|
1523
1563
|
declare const RESERVED_NAVIGATION_SLUGS: Set<string>;
|
|
1524
1564
|
/**
|
|
1525
|
-
* Validates that no navigation item uses a reserved system route slug.
|
|
1565
|
+
* Validates that no navigation item uses a reserved system route slug or duplicate slug.
|
|
1526
1566
|
*/
|
|
1527
1567
|
declare function assertValidNavigationSlugs(navigation: DefineWorkspaceOptions[]): void;
|
|
1528
1568
|
/**
|
|
@@ -2340,4 +2380,4 @@ declare function defineTab<const T extends readonly Field[]>(args: {
|
|
|
2340
2380
|
fields: T;
|
|
2341
2381
|
}): T;
|
|
2342
2382
|
|
|
2343
|
-
export { AIConfig, type AIErrorCode, AIPIIConfig, type AccessConditions, AccessPolicyResolver, AdminAuthConfig, ArrayField, AuthConfig, type AuthDocFields, AuthenticatedUser, BASE62_ALPHABET, BUILTIN_JEXL_HELPERS, BaseDocument, Block, BooleanField, CROCKFORD_BASE32, CollectionConfig, CompiledNavItem, CompiledNavTree, ComputedHandler, type ConfigDiagnostic, ConfigValidationError, ConflictError, type CreatedAtFieldOptions, type CreatedByFieldOptions, DatabaseAdapter, DateField, DateTimeField, type DeclarativeAccessSurface, type DeclarativeAccessValidationIssue, type DeclarativeAdminSurface, type DeclarativeAdminValidationIssue, DeclarativeHookExpression, type DeclarativeHookSurface, type DeclarativeHookValidationIssue, type DeclarativePreviewSurface, type DeclarativePreviewValidationIssue, DefineWorkspaceOptions, DetailAction, DetailActionOptions, DetailComputed, DetailComputedOptions, DetailCustom, DetailCustomOptions, DetailDivider, DetailDividerOptions, DetailField, DetailGrid, DetailGridOptions, DetailItem, DetailRepeat, DetailRepeatOptions, DetailSchema, DetailSection, DetailSectionOptions, DetailTab, DetailTabOptions, DetailTabs, DetailTabsOptions, DetailText, DetailTextOptions, DisplayFieldOptions, DuplicateKeyError, DyrectedAIError, DyrectedConfig, DyrectedError, EMAIL_TEMPLATES_COLLECTION_CONFIG, EMAIL_TEMPLATES_COLLECTION_SLUG, EmailField, type ExprFunction, type ExtractCollectionSlugs, Field, FieldConditionBuilder, FieldType, ForbiddenError, type GenerateIdOptions, GlobalConfig, HookRequestContext, INTERNAL_SYSTEM_COLLECTIONS, IconField, IdStrategy, ImageField, type InferDocShape, JoinField, JsonField, LIFECYCLE_EVENTS_COLLECTION, type LayoutOptions, LifecycleEvent, LifecycleEventName, MatchBuilder, MoneyField, MultiSelectField, NANOID_ALPHABET, NON_NEGOTIABLE_CREDENTIAL_FIELDS, NotFoundError, NumberField, ObjectField, PII_REGEX_PATTERNS, type Prettify, PublicAdminAuthConfig, type PublishingWorkflowOptions, RESERVED_NAVIGATION_SLUGS, RadioField, type ReconcileNavigationOptions, type ReconciledNavTree, RelationshipField, type ResolvedTrashConfig, type RestoreDocumentOptions, RichTextField, type RoleOption, type RolesFieldOptions, RowField, type SanitizeDocForAIOptions, SelectField, type SoftDeleteOptions, type SortClause, type SortDirection, type SqlSortDialect, type SystemDocFields, TASK_LOCKS_COLLECTION, TASK_LOCKS_COLLECTION_CONFIG, TRASH_COLLECTION, TRASH_COLLECTION_CONFIG, TaskConfig, TaskRunResult, type TaskRunner, type TemplateBlock, TextField, TextareaField, TimeField, UNASSIGNED_GROUP_KEY, type UpdatedAtFieldOptions, type UpdatedByFieldOptions, type UploadDocFields, UrlField, UserNavigationPreferences, ValidationError, ViewConfig, WORKFLOW_HISTORY_COLLECTION, type WhenFunction, WorkflowConfig, WorkflowTransition, abs, addDays, alertBox, asCollection, assertValidAdminConditionsInConfig, assertValidDeclarativeAccessInConfig, assertValidDeclarativeHookExpression, assertValidDeclarativeHookResult, assertValidDeclarativeHooksInConfig, assertValidNavigationSlugs, assertValidPreviewUrlsInConfig, assertValidTrashInConfig, availableWorkflowTransitions, buildSqlOrderBy, canViewWorkflowDraft, capitalize, ceil, clamp, coalesce, collectAdminConditionValidationIssues, collectConfigDiagnostics, collectDeclarativeAccessValidationIssues, collectDeclarativeHookValidationIssues, collectPreviewUrlValidationIssues, compact, compileNavigation, count, createLifecycleEvent, createTaskRunner, createTrashPurgeTask, createWorkflowDocument, ctaButton, defaultValue, defineArrayField, defineBlock, defineBlocksField, defineBooleanField, defineCollection, defineConfig, defineCreatedAtField, defineCreatedByField, defineDateField, defineDateTimeField, defineEmailField, defineField, defineGlobal, defineIconField, defineImageField, defineJoinField, defineJsonField, defineMoneyField, defineMultiSelectField, defineNumberField, defineObjectField, definePublishingWorkflow, defineRadioField, defineRelationshipField, defineRichTextField, defineRoles, defineRolesField, defineRowField, defineSelectField, defineTab, defineTask, defineTextField, defineTextareaField, defineTimeField, defineUpdatedAtField, defineUpdatedByField, defineUrlField, detailBox, diffDays, dispatchLifecycleEvent, dispatchPendingLifecycleEvents, displayAction, displayComputed, displayCustom, displayCustomComponent, displayDivider, displayField, displayGrid, displayRepeat, displaySection, displayTab, displayTabs, displayText, divider, emailTokens, endsWith, escapeHtml, evaluateDetailComputed, evaluateJexl, evaluateJexlSync, eventList, executeFieldAfterRead, executeFieldBeforeChange, expr, first, floor, formatConfigDiagnostics, formatDate, formatJexlValue, generateDefaultDetailSchema, generateDocumentId, generateId, generateOpenApi, get, getAdminAuthCollection, getAdminRoleForCollection, getAllowedSitesForUser, getDefaultEmailTemplate, getPublicAdminAuthConfig, getTrashEntryId, heading, includes, initializeWorkflowDocument, isConfigValidationError, isDetailItemVisible, isEmpty, isFuture, isPast, isSiteAuthorized, isUserAdmin, join, last, layout, length, lower, maskEmail, maskPhone, maskTextPII, materializeWorkflowDocument, max, min, nanoid, nextCronRun, normalizeConfig, normalizeDetailItem, normalizeGroupKey, now, numericFieldNames, paragraph, parseCron, parseSort, pow, prefixedId, pruneNavigationForUser, publishedStateName, publishingWorkflow, readingTime, reconcileNavigation, registerJexlHelpers, replace, resolveAdminAuthCollection, resolveAllCollectionViews, resolveAuthorizedSiteId, resolveBlocks, resolveDocumentTitle, resolveIndexName, resolvePrefix, resolveTrashConfig, restoreDocument, round, row, runCollectionHooks, safeLinkDetailBox, sanitizeDocForAI, saveWorkflowDraft, sectionLabel, simplePublishingWorkflow, slugify, softDeleteDocument, spacer, sqrt, startsWith, sum, table, today, transitionWorkflow, trim, truncate, ulid, unique, upper, uuid, validateAdminConditionExpression, validateDeclarativeAccessExpression, validateDeclarativeHookExpression, validatePreviewUrlExpression, when, wordCount, workflowCapabilities };
|
|
2383
|
+
export { AIConfig, type AIErrorCode, AIPIIConfig, type AccessConditions, AccessPolicyResolver, AdminAuthConfig, type AdminComponentsValidationIssue, ArrayField, AuthConfig, type AuthDocFields, AuthenticatedUser, BASE62_ALPHABET, BUILTIN_JEXL_HELPERS, BaseDocument, Block, BooleanField, CROCKFORD_BASE32, CollectionConfig, CompiledNavItem, CompiledNavTree, ComputedHandler, type ConfigDiagnostic, ConfigValidationError, ConflictError, type CreatedAtFieldOptions, type CreatedByFieldOptions, DatabaseAdapter, DateField, DateTimeField, type DeclarativeAccessSurface, type DeclarativeAccessValidationIssue, type DeclarativeAdminSurface, type DeclarativeAdminValidationIssue, DeclarativeHookExpression, type DeclarativeHookSurface, type DeclarativeHookValidationIssue, type DeclarativePreviewSurface, type DeclarativePreviewValidationIssue, DefineWorkspaceOptions, DetailAction, DetailActionOptions, DetailComputed, DetailComputedOptions, DetailCustom, DetailCustomOptions, DetailDivider, DetailDividerOptions, DetailField, DetailGrid, DetailGridOptions, DetailItem, DetailRepeat, DetailRepeatOptions, DetailSchema, DetailSection, DetailSectionOptions, DetailTab, DetailTabOptions, DetailTabs, DetailTabsOptions, DetailText, DetailTextOptions, DisplayFieldOptions, DuplicateKeyError, DyrectedAIError, DyrectedConfig, DyrectedError, EMAIL_TEMPLATES_COLLECTION_CONFIG, EMAIL_TEMPLATES_COLLECTION_SLUG, EmailField, type ExprFunction, type ExtractCollectionSlugs, Field, FieldConditionBuilder, FieldType, ForbiddenError, type GenerateIdOptions, GlobalConfig, HookRequestContext, INTERNAL_SYSTEM_COLLECTIONS, IconField, IdStrategy, ImageField, type InferDocShape, JoinField, JsonField, LIFECYCLE_EVENTS_COLLECTION, type LayoutOptions, LifecycleEvent, LifecycleEventName, MatchBuilder, MoneyField, MultiSelectField, NANOID_ALPHABET, NON_NEGOTIABLE_CREDENTIAL_FIELDS, NotFoundError, NumberField, ObjectField, PII_REGEX_PATTERNS, type Prettify, PublicAdminAuthConfig, type PublishingWorkflowOptions, RESERVED_NAVIGATION_SLUGS, RadioField, type ReconcileNavigationOptions, type ReconciledNavTree, type ReferencedComponentKeys, RelationshipField, type ResolvedTrashConfig, type RestoreDocumentOptions, RichTextField, type RoleOption, type RolesFieldOptions, RowField, type SanitizeDocForAIOptions, SelectField, type SoftDeleteOptions, type SortClause, type SortDirection, type SqlSortDialect, type SystemDocFields, TASK_LOCKS_COLLECTION, TASK_LOCKS_COLLECTION_CONFIG, TRASH_COLLECTION, TRASH_COLLECTION_CONFIG, TaskConfig, TaskRunResult, type TaskRunner, type TemplateBlock, TextField, TextareaField, TimeField, UNASSIGNED_GROUP_KEY, type UpdatedAtFieldOptions, type UpdatedByFieldOptions, type UploadDocFields, UrlField, UserNavigationPreferences, ValidationError, ViewConfig, WORKFLOW_HISTORY_COLLECTION, type WhenFunction, WorkflowConfig, WorkflowTransition, abs, addDays, alertBox, asCollection, assertValidAdminConditionsInConfig, assertValidDeclarativeAccessInConfig, assertValidDeclarativeHookExpression, assertValidDeclarativeHookResult, assertValidDeclarativeHooksInConfig, assertValidNavigationSlugs, assertValidPreviewUrlsInConfig, assertValidTrashInConfig, availableWorkflowTransitions, buildSqlOrderBy, canViewWorkflowDraft, capitalize, ceil, clamp, coalesce, collectAdminComponentsValidationIssues, collectAdminConditionValidationIssues, collectConfigDiagnostics, collectDeclarativeAccessValidationIssues, collectDeclarativeHookValidationIssues, collectPreviewUrlValidationIssues, collectReferencedComponentKeys, compact, compileNavigation, count, createLifecycleEvent, createTaskRunner, createTrashPurgeTask, createWorkflowDocument, ctaButton, defaultValue, defineArrayField, defineBlock, defineBlocksField, defineBooleanField, defineCollection, defineConfig, defineCreatedAtField, defineCreatedByField, defineDateField, defineDateTimeField, defineEmailField, defineField, defineGlobal, defineIconField, defineImageField, defineJoinField, defineJsonField, defineMoneyField, defineMultiSelectField, defineNumberField, defineObjectField, definePublishingWorkflow, defineRadioField, defineRelationshipField, defineRichTextField, defineRoles, defineRolesField, defineRowField, defineSelectField, defineTab, defineTask, defineTextField, defineTextareaField, defineTimeField, defineUpdatedAtField, defineUpdatedByField, defineUrlField, detailBox, diffDays, dispatchLifecycleEvent, dispatchPendingLifecycleEvents, displayAction, displayComputed, displayCustom, displayCustomComponent, displayDivider, displayField, displayGrid, displayRepeat, displaySection, displayTab, displayTabs, displayText, divider, emailTokens, endsWith, escapeHtml, evaluateDetailComputed, evaluateJexl, evaluateJexlSync, eventList, executeFieldAfterRead, executeFieldBeforeChange, expr, first, floor, formatConfigDiagnostics, formatDate, formatJexlValue, generateDefaultDetailSchema, generateDocumentId, generateId, generateOpenApi, get, getAdminAuthCollection, getAdminRoleForCollection, getAllowedSitesForUser, getDefaultEmailTemplate, getPublicAdminAuthConfig, getTrashEntryId, heading, includes, initializeWorkflowDocument, isConfigValidationError, isDetailItemVisible, isEmpty, isFuture, isPast, isSiteAuthorized, isUserAdmin, join, last, layout, length, lower, maskEmail, maskPhone, maskTextPII, materializeWorkflowDocument, max, min, nanoid, nextCronRun, normalizeConfig, normalizeDetailItem, normalizeGroupKey, now, numericFieldNames, paragraph, parseCron, parseSort, pow, prefixedId, pruneNavigationForUser, publishedStateName, publishingWorkflow, readingTime, reconcileNavigation, registerJexlHelpers, replace, resolveAdminAuthCollection, resolveAllCollectionViews, resolveAuthorizedSiteId, resolveBlocks, resolveDocumentTitle, resolveIndexName, resolvePrefix, resolveTrashConfig, restoreDocument, round, row, runCollectionHooks, safeLinkDetailBox, sanitizeDocForAI, saveWorkflowDraft, sectionLabel, simplePublishingWorkflow, slugify, softDeleteDocument, spacer, sqrt, startsWith, sum, table, today, transitionWorkflow, trim, truncate, ulid, unique, upper, uuid, validateAdminConditionExpression, validateDeclarativeAccessExpression, validateDeclarativeHookExpression, validatePreviewUrlExpression, when, wordCount, workflowCapabilities };
|
package/dist/index.js
CHANGED
|
@@ -1780,6 +1780,9 @@ function asCollection(config) {
|
|
|
1780
1780
|
return config;
|
|
1781
1781
|
}
|
|
1782
1782
|
|
|
1783
|
+
// src/types/admin.ts
|
|
1784
|
+
var FORM_SHELLS = ["full", "header", "none"];
|
|
1785
|
+
|
|
1783
1786
|
// src/types/workflows.ts
|
|
1784
1787
|
var LIFECYCLE_EVENT_NAMES = [
|
|
1785
1788
|
"revision.created",
|
|
@@ -1789,9 +1792,19 @@ var LIFECYCLE_EVENT_NAMES = [
|
|
|
1789
1792
|
];
|
|
1790
1793
|
|
|
1791
1794
|
// src/types/views.ts
|
|
1795
|
+
var CUSTOM_VIEW_FETCH_ALL_LIMIT = 1e3;
|
|
1792
1796
|
function defineView(config) {
|
|
1797
|
+
assertCustomViewComponent(config);
|
|
1793
1798
|
return config;
|
|
1794
1799
|
}
|
|
1800
|
+
function assertCustomViewComponent(config) {
|
|
1801
|
+
if (config.layout !== "custom") return;
|
|
1802
|
+
if (typeof config.component !== "string" || config.component.trim() === "") {
|
|
1803
|
+
throw new Error(
|
|
1804
|
+
`View "${config.slug ?? "(unnamed)"}" uses layout: "custom" but has no \`component\`. Set \`component\` to a key registered in AdminComponents.viewLayouts.`
|
|
1805
|
+
);
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1795
1808
|
function defineTableView(config) {
|
|
1796
1809
|
return config;
|
|
1797
1810
|
}
|
|
@@ -1804,6 +1817,10 @@ function defineCalendarView(config) {
|
|
|
1804
1817
|
function defineGanttView(config) {
|
|
1805
1818
|
return config;
|
|
1806
1819
|
}
|
|
1820
|
+
function defineCustomView(config) {
|
|
1821
|
+
assertCustomViewComponent(config);
|
|
1822
|
+
return config;
|
|
1823
|
+
}
|
|
1807
1824
|
function defineCardsView(config) {
|
|
1808
1825
|
return config;
|
|
1809
1826
|
}
|
|
@@ -1860,6 +1877,23 @@ var DEFAULT_USER_NAV_PREFERENCES = {
|
|
|
1860
1877
|
items: []
|
|
1861
1878
|
};
|
|
1862
1879
|
|
|
1880
|
+
// src/types/pages.ts
|
|
1881
|
+
function definePage(config) {
|
|
1882
|
+
return {
|
|
1883
|
+
slug: config.slug,
|
|
1884
|
+
label: config.label,
|
|
1885
|
+
icon: config.icon,
|
|
1886
|
+
group: config.group,
|
|
1887
|
+
order: config.order,
|
|
1888
|
+
after: config.after,
|
|
1889
|
+
before: config.before,
|
|
1890
|
+
position: config.position,
|
|
1891
|
+
badge: config.badge,
|
|
1892
|
+
access: config.access && typeof config.access === "object" && "read" in config.access ? config.access.read : config.access,
|
|
1893
|
+
page: config
|
|
1894
|
+
};
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1863
1897
|
// src/auth/token.ts
|
|
1864
1898
|
import { SignJWT, jwtVerify, decodeJwt } from "jose";
|
|
1865
1899
|
|
|
@@ -2699,6 +2733,54 @@ function collectPreviewUrlValidationIssues(config) {
|
|
|
2699
2733
|
});
|
|
2700
2734
|
return issues;
|
|
2701
2735
|
}
|
|
2736
|
+
var FORM_COMPONENT_KEYS = ["createForm", "editForm", "form"];
|
|
2737
|
+
var GLOBAL_FORM_COMPONENT_KEYS = ["editForm", "form"];
|
|
2738
|
+
function collectFormComponentIssues(components, path, surface, keys, issues) {
|
|
2739
|
+
if (!isPlainObject(components)) return;
|
|
2740
|
+
for (const key of keys) {
|
|
2741
|
+
const value = components[key];
|
|
2742
|
+
if (value === void 0) continue;
|
|
2743
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
2744
|
+
issues.push({
|
|
2745
|
+
path: `${path}.admin.components.${key}`,
|
|
2746
|
+
surface,
|
|
2747
|
+
message: `\`${key}\` must be the registry key of a component, such as "check_ins.scanForm".`,
|
|
2748
|
+
expression: String(value)
|
|
2749
|
+
});
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2752
|
+
const shell = components.formShell;
|
|
2753
|
+
if (shell !== void 0 && !FORM_SHELLS.includes(shell)) {
|
|
2754
|
+
issues.push({
|
|
2755
|
+
path: `${path}.admin.components.formShell`,
|
|
2756
|
+
surface,
|
|
2757
|
+
message: `Unknown formShell "${String(shell)}". Use ${FORM_SHELLS.map((value) => `"${value}"`).join(", ")}.`,
|
|
2758
|
+
expression: String(shell)
|
|
2759
|
+
});
|
|
2760
|
+
}
|
|
2761
|
+
}
|
|
2762
|
+
function collectAdminComponentsValidationIssues(config) {
|
|
2763
|
+
const issues = [];
|
|
2764
|
+
config.collections.forEach((collection, index) => {
|
|
2765
|
+
collectFormComponentIssues(
|
|
2766
|
+
collection.admin?.components,
|
|
2767
|
+
collectionSegment(collection, index),
|
|
2768
|
+
"collection.admin.components",
|
|
2769
|
+
FORM_COMPONENT_KEYS,
|
|
2770
|
+
issues
|
|
2771
|
+
);
|
|
2772
|
+
});
|
|
2773
|
+
config.globals?.forEach((global, index) => {
|
|
2774
|
+
collectFormComponentIssues(
|
|
2775
|
+
global.admin?.components,
|
|
2776
|
+
globalSegment(global, index),
|
|
2777
|
+
"global.admin.components",
|
|
2778
|
+
GLOBAL_FORM_COMPONENT_KEYS,
|
|
2779
|
+
issues
|
|
2780
|
+
);
|
|
2781
|
+
});
|
|
2782
|
+
return issues;
|
|
2783
|
+
}
|
|
2702
2784
|
function assertValidAdminConditionsInConfig(config, source = "config") {
|
|
2703
2785
|
const diagnostics = collectAdminConditionValidationIssues(config).map((issue) => ({
|
|
2704
2786
|
severity: "error",
|
|
@@ -2756,7 +2838,15 @@ function collectConfigDiagnostics(config) {
|
|
|
2756
2838
|
message: issue.message,
|
|
2757
2839
|
expression: issue.expression
|
|
2758
2840
|
}));
|
|
2759
|
-
|
|
2841
|
+
const adminComponentIssues = collectAdminComponentsValidationIssues(config).map((issue) => ({
|
|
2842
|
+
severity: "error",
|
|
2843
|
+
source: "adminComponents",
|
|
2844
|
+
path: issue.path,
|
|
2845
|
+
surface: issue.surface,
|
|
2846
|
+
message: issue.message,
|
|
2847
|
+
expression: issue.expression
|
|
2848
|
+
}));
|
|
2849
|
+
return [...hookIssues, ...accessIssues, ...adminConditionIssues, ...previewUrlIssues, ...adminComponentIssues];
|
|
2760
2850
|
}
|
|
2761
2851
|
function formatConfigDiagnostics(source, diagnostics, options = {}) {
|
|
2762
2852
|
const color = options.color ?? false;
|
|
@@ -5189,6 +5279,12 @@ var DuplicateKeyError = class _DuplicateKeyError extends ConflictError {
|
|
|
5189
5279
|
function assertNever(op, context) {
|
|
5190
5280
|
throw new Error(`[dyrected/core] Unhandled where operator "${op}" in ${context}`);
|
|
5191
5281
|
}
|
|
5282
|
+
function escapeLike(value) {
|
|
5283
|
+
return value.replace(/[!%_]/g, "!$&");
|
|
5284
|
+
}
|
|
5285
|
+
function escapeRegex(value) {
|
|
5286
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5287
|
+
}
|
|
5192
5288
|
function parseSqlWhere(where, getJsonField, placeholder = "?", likeOperator = placeholder === "pg" ? "ILIKE" : "LIKE") {
|
|
5193
5289
|
const params = [];
|
|
5194
5290
|
let pgIndex = 1;
|
|
@@ -5198,6 +5294,19 @@ function parseSqlWhere(where, getJsonField, placeholder = "?", likeOperator = pl
|
|
|
5198
5294
|
function col(field) {
|
|
5199
5295
|
return field === "id" ? "id" : getJsonField(field);
|
|
5200
5296
|
}
|
|
5297
|
+
function buildLike(column, pattern, escaped = false) {
|
|
5298
|
+
const esc = escaped ? ` ESCAPE '!'` : "";
|
|
5299
|
+
if (placeholder === "pg") {
|
|
5300
|
+
params.push(pattern);
|
|
5301
|
+
return `(${column})::text ${likeOperator} ${next()}${esc}`;
|
|
5302
|
+
}
|
|
5303
|
+
if (likeOperator === "ILIKE") {
|
|
5304
|
+
params.push(pattern);
|
|
5305
|
+
return `${column} ILIKE ${next()}${esc}`;
|
|
5306
|
+
}
|
|
5307
|
+
params.push(pattern.toLowerCase());
|
|
5308
|
+
return `LOWER(${column}) LIKE ${next()}${esc}`;
|
|
5309
|
+
}
|
|
5201
5310
|
function buildOperator(field, value) {
|
|
5202
5311
|
const c = col(field);
|
|
5203
5312
|
const isJsonExtract = c.startsWith("data->>") || c.startsWith("json_extract(") || c.startsWith("JSON_UNQUOTE(");
|
|
@@ -5340,13 +5449,12 @@ function parseSqlWhere(where, getJsonField, placeholder = "?", likeOperator = pl
|
|
|
5340
5449
|
case "less_than_or_equal":
|
|
5341
5450
|
params.push(operand);
|
|
5342
5451
|
return `${c} <= ${next()}`;
|
|
5343
|
-
case "contains":
|
|
5344
5452
|
case "like":
|
|
5345
|
-
|
|
5346
|
-
|
|
5453
|
+
return buildLike(c, `%${String(operand)}%`);
|
|
5454
|
+
case "contains":
|
|
5455
|
+
return buildLike(c, `%${escapeLike(String(operand))}%`, true);
|
|
5347
5456
|
case "starts_with":
|
|
5348
|
-
|
|
5349
|
-
return placeholder === "pg" ? `(${c})::text ${likeOperator} ${next()}` : `${c} ${likeOperator} ${next()}`;
|
|
5457
|
+
return buildLike(c, `${escapeLike(String(operand))}%`, true);
|
|
5350
5458
|
case "exists":
|
|
5351
5459
|
return operand ? `${c} IS NOT NULL` : `${c} IS NULL`;
|
|
5352
5460
|
default:
|
|
@@ -5444,9 +5552,9 @@ function parseMongoWhere(where) {
|
|
|
5444
5552
|
return { [field]: { $lte: operand } };
|
|
5445
5553
|
case "contains":
|
|
5446
5554
|
case "like":
|
|
5447
|
-
return { [field]: { $regex: operand, $options: "i" } };
|
|
5555
|
+
return { [field]: { $regex: escapeRegex(String(operand)), $options: "i" } };
|
|
5448
5556
|
case "starts_with":
|
|
5449
|
-
return { [field]: { $regex: `^${operand}`, $options: "i" } };
|
|
5557
|
+
return { [field]: { $regex: `^${escapeRegex(String(operand))}`, $options: "i" } };
|
|
5450
5558
|
case "exists":
|
|
5451
5559
|
return { [field]: { $exists: operand } };
|
|
5452
5560
|
default:
|
|
@@ -5556,6 +5664,99 @@ function buildSqlOrderBy(sort, existingColumns, numericFields, dialect) {
|
|
|
5556
5664
|
}).join(", ");
|
|
5557
5665
|
}
|
|
5558
5666
|
|
|
5667
|
+
// src/utils/component-keys.ts
|
|
5668
|
+
var DASHBOARD_SLOTS = ["beforeDashboard", "afterDashboard"];
|
|
5669
|
+
var LIST_SLOTS = ["beforeList", "beforeListTable", "afterListTable", "afterList"];
|
|
5670
|
+
var FORM_SLOTS = ["createForm", "editForm", "form"];
|
|
5671
|
+
var VIEW_SLOTS = ["beforeViewHeader", "afterViewHeader", "beforeViewContent", "afterViewContent"];
|
|
5672
|
+
function addKeys(target, value) {
|
|
5673
|
+
for (const key of Array.isArray(value) ? value : [value]) {
|
|
5674
|
+
if (typeof key === "string" && key) target.add(key);
|
|
5675
|
+
}
|
|
5676
|
+
}
|
|
5677
|
+
function addSlots(target, slots, names) {
|
|
5678
|
+
if (!slots || typeof slots !== "object") return;
|
|
5679
|
+
for (const name of names) addKeys(target, slots[name]);
|
|
5680
|
+
}
|
|
5681
|
+
function scanFields(fields, keys) {
|
|
5682
|
+
if (!Array.isArray(fields)) return;
|
|
5683
|
+
for (const field of fields) {
|
|
5684
|
+
if (!field || typeof field !== "object") continue;
|
|
5685
|
+
addKeys(keys.fields, field.admin?.component);
|
|
5686
|
+
scanFields(field.fields, keys);
|
|
5687
|
+
if (Array.isArray(field.blocks)) {
|
|
5688
|
+
for (const block of field.blocks) scanFields(block?.fields, keys);
|
|
5689
|
+
}
|
|
5690
|
+
if (Array.isArray(field.tabs)) {
|
|
5691
|
+
for (const tab of field.tabs) scanFields(tab?.fields, keys);
|
|
5692
|
+
}
|
|
5693
|
+
}
|
|
5694
|
+
}
|
|
5695
|
+
function scanDetail(items, keys) {
|
|
5696
|
+
if (!Array.isArray(items)) return;
|
|
5697
|
+
for (const item of items) {
|
|
5698
|
+
if (!item || typeof item !== "object") continue;
|
|
5699
|
+
if (item.type === "custom") addKeys(keys.customComponents, item.name);
|
|
5700
|
+
scanDetail(item.items, keys);
|
|
5701
|
+
if (Array.isArray(item.tabs)) {
|
|
5702
|
+
for (const tab of item.tabs) scanDetail(tab?.items, keys);
|
|
5703
|
+
}
|
|
5704
|
+
}
|
|
5705
|
+
}
|
|
5706
|
+
function scanViews(views, keys) {
|
|
5707
|
+
if (!Array.isArray(views)) return;
|
|
5708
|
+
for (const view of views) {
|
|
5709
|
+
addSlots(keys.collectionView, view?.components, VIEW_SLOTS);
|
|
5710
|
+
if (view?.layout === "custom") addKeys(keys.viewLayouts, view.component);
|
|
5711
|
+
}
|
|
5712
|
+
}
|
|
5713
|
+
function collectReferencedComponentKeys(schema) {
|
|
5714
|
+
const keys = {
|
|
5715
|
+
fields: /* @__PURE__ */ new Set(),
|
|
5716
|
+
dashboard: /* @__PURE__ */ new Set(),
|
|
5717
|
+
collectionList: /* @__PURE__ */ new Set(),
|
|
5718
|
+
collectionView: /* @__PURE__ */ new Set(),
|
|
5719
|
+
forms: /* @__PURE__ */ new Set(),
|
|
5720
|
+
viewLayouts: /* @__PURE__ */ new Set(),
|
|
5721
|
+
pages: /* @__PURE__ */ new Set(),
|
|
5722
|
+
customComponents: /* @__PURE__ */ new Set()
|
|
5723
|
+
};
|
|
5724
|
+
const root = schema;
|
|
5725
|
+
if (!root || typeof root !== "object") return keys;
|
|
5726
|
+
addSlots(keys.dashboard, root.admin?.components, DASHBOARD_SLOTS);
|
|
5727
|
+
if (Array.isArray(root.admin?.navigation)) {
|
|
5728
|
+
for (const item of root.admin.navigation) {
|
|
5729
|
+
if (item?.page) {
|
|
5730
|
+
if (typeof item.page === "string") {
|
|
5731
|
+
addKeys(keys.pages, item.page);
|
|
5732
|
+
} else if (item.page?.component) {
|
|
5733
|
+
addKeys(keys.pages, item.page.component);
|
|
5734
|
+
}
|
|
5735
|
+
}
|
|
5736
|
+
}
|
|
5737
|
+
}
|
|
5738
|
+
if (Array.isArray(root.admin?.pages)) {
|
|
5739
|
+
for (const page of root.admin.pages) addKeys(keys.pages, page?.component);
|
|
5740
|
+
}
|
|
5741
|
+
for (const block of root.blocks ?? []) scanFields(block?.fields, keys);
|
|
5742
|
+
for (const collection of root.collections ?? []) {
|
|
5743
|
+
scanFields(collection.fields, keys);
|
|
5744
|
+
scanDetail(collection.detail, keys);
|
|
5745
|
+
scanViews(collection.views, keys);
|
|
5746
|
+
const slots = collection.admin?.components;
|
|
5747
|
+
addSlots(keys.collectionList, slots, LIST_SLOTS);
|
|
5748
|
+
addSlots(keys.collectionView, slots, VIEW_SLOTS);
|
|
5749
|
+
addSlots(keys.collectionView, slots?.collectionView, VIEW_SLOTS);
|
|
5750
|
+
addSlots(keys.forms, slots, FORM_SLOTS);
|
|
5751
|
+
}
|
|
5752
|
+
for (const global of root.globals ?? []) {
|
|
5753
|
+
scanFields(global.fields, keys);
|
|
5754
|
+
scanDetail(global.detail, keys);
|
|
5755
|
+
addSlots(keys.forms, global.admin?.components, FORM_SLOTS);
|
|
5756
|
+
}
|
|
5757
|
+
return keys;
|
|
5758
|
+
}
|
|
5759
|
+
|
|
5559
5760
|
// src/utils/openapi.ts
|
|
5560
5761
|
function getCollectionLabels(collection) {
|
|
5561
5762
|
return collection.labels || { singular: collection.slug, plural: collection.slug };
|
|
@@ -8043,11 +8244,32 @@ var RESERVED_NAVIGATION_SLUGS = /* @__PURE__ */ new Set([
|
|
|
8043
8244
|
"admin",
|
|
8044
8245
|
"preferences",
|
|
8045
8246
|
"auth",
|
|
8046
|
-
"trash"
|
|
8247
|
+
"trash",
|
|
8248
|
+
"pages"
|
|
8047
8249
|
]);
|
|
8048
8250
|
function assertValidNavigationSlugs(navigation) {
|
|
8251
|
+
const seenWorkspaceSlugs = /* @__PURE__ */ new Set();
|
|
8252
|
+
const seenPageSlugs = /* @__PURE__ */ new Set();
|
|
8049
8253
|
for (const item of navigation) {
|
|
8050
8254
|
if (item.dashboard || item.trash) continue;
|
|
8255
|
+
if (item.page) {
|
|
8256
|
+
const pageSlug = typeof item.page === "string" ? item.slug || item.page : item.slug || item.page.slug;
|
|
8257
|
+
if (pageSlug) {
|
|
8258
|
+
const normalized = pageSlug.toLowerCase().trim().replace(/^\//, "");
|
|
8259
|
+
if (RESERVED_NAVIGATION_SLUGS.has(normalized)) {
|
|
8260
|
+
throw new Error(
|
|
8261
|
+
`[Dyrected Config] The slug '${pageSlug}' in custom page '${item.label || pageSlug}' is a reserved system path and cannot be used as a page slug.`
|
|
8262
|
+
);
|
|
8263
|
+
}
|
|
8264
|
+
if (seenPageSlugs.has(normalized)) {
|
|
8265
|
+
throw new Error(
|
|
8266
|
+
`[Dyrected Config] Duplicate page slug '${pageSlug}' in navigation. Page slugs must be unique.`
|
|
8267
|
+
);
|
|
8268
|
+
}
|
|
8269
|
+
seenPageSlugs.add(normalized);
|
|
8270
|
+
}
|
|
8271
|
+
continue;
|
|
8272
|
+
}
|
|
8051
8273
|
if (item.slug) {
|
|
8052
8274
|
const normalizedSlug = item.slug.toLowerCase().trim().replace(/^\//, "");
|
|
8053
8275
|
if (RESERVED_NAVIGATION_SLUGS.has(normalizedSlug)) {
|
|
@@ -8055,6 +8277,12 @@ function assertValidNavigationSlugs(navigation) {
|
|
|
8055
8277
|
`[Dyrected Config] The slug '${item.slug}' in navigation item '${item.label || item.slug}' is a reserved system path and cannot be used as an operational workspace slug.`
|
|
8056
8278
|
);
|
|
8057
8279
|
}
|
|
8280
|
+
if (seenWorkspaceSlugs.has(normalizedSlug)) {
|
|
8281
|
+
throw new Error(
|
|
8282
|
+
`[Dyrected Config] Duplicate workspace slug '${item.slug}' in navigation. Workspace slugs must be unique.`
|
|
8283
|
+
);
|
|
8284
|
+
}
|
|
8285
|
+
seenWorkspaceSlugs.add(normalizedSlug);
|
|
8058
8286
|
}
|
|
8059
8287
|
}
|
|
8060
8288
|
}
|
|
@@ -8197,6 +8425,43 @@ function compileNavigation(config) {
|
|
|
8197
8425
|
});
|
|
8198
8426
|
continue;
|
|
8199
8427
|
}
|
|
8428
|
+
if (item.page) {
|
|
8429
|
+
const pageConfig = typeof item.page === "string" ? {
|
|
8430
|
+
slug: item.slug || item.page,
|
|
8431
|
+
label: item.label || item.page,
|
|
8432
|
+
icon: item.icon,
|
|
8433
|
+
component: item.page,
|
|
8434
|
+
group: typeof item.group === "string" ? item.group : item.group?.name,
|
|
8435
|
+
order: item.order,
|
|
8436
|
+
badge: item.badge,
|
|
8437
|
+
access: item.access
|
|
8438
|
+
} : {
|
|
8439
|
+
...item.page,
|
|
8440
|
+
slug: item.slug || item.page.slug || "page",
|
|
8441
|
+
label: item.label || item.page.label || item.slug || "Page",
|
|
8442
|
+
icon: item.icon || item.page.icon,
|
|
8443
|
+
group: item.group ? typeof item.group === "string" ? item.group : item.group?.name : item.page.group,
|
|
8444
|
+
order: item.order ?? item.page.order,
|
|
8445
|
+
badge: item.badge || item.page.badge,
|
|
8446
|
+
access: item.access || (item.page.access && typeof item.page.access === "object" && "read" in item.page.access ? item.page.access.read : item.page.access)
|
|
8447
|
+
};
|
|
8448
|
+
const pageSlug = pageConfig.slug || "page";
|
|
8449
|
+
registerItem(groupName, {
|
|
8450
|
+
id: `page:${pageSlug}`,
|
|
8451
|
+
type: "page",
|
|
8452
|
+
slug: pageSlug,
|
|
8453
|
+
label: pageConfig.label || pageSlug,
|
|
8454
|
+
icon: pageConfig.icon || "FileText",
|
|
8455
|
+
href: `/pages/${pageSlug}`,
|
|
8456
|
+
group: groupName,
|
|
8457
|
+
order: pageConfig.order ?? 100,
|
|
8458
|
+
views: [],
|
|
8459
|
+
badge: pageConfig.badge,
|
|
8460
|
+
access: pageConfig.access && typeof pageConfig.access === "object" && "read" in pageConfig.access ? pageConfig.access.read : pageConfig.access,
|
|
8461
|
+
page: pageConfig
|
|
8462
|
+
});
|
|
8463
|
+
continue;
|
|
8464
|
+
}
|
|
8200
8465
|
const workspaceSlug = item.slug || "workspace";
|
|
8201
8466
|
registerItem(groupName, {
|
|
8202
8467
|
id: `workspace_${workspaceSlug}`,
|
|
@@ -8578,6 +8843,7 @@ export {
|
|
|
8578
8843
|
BUILTIN_JEXL_HELPERS,
|
|
8579
8844
|
CROCKFORD_BASE32,
|
|
8580
8845
|
CURRENT_NAV_PREFERENCES_VERSION,
|
|
8846
|
+
CUSTOM_VIEW_FETCH_ALL_LIMIT,
|
|
8581
8847
|
ConfigValidationError,
|
|
8582
8848
|
ConflictError,
|
|
8583
8849
|
DEFAULT_USER_NAV_PREFERENCES,
|
|
@@ -8586,6 +8852,7 @@ export {
|
|
|
8586
8852
|
DyrectedError,
|
|
8587
8853
|
EMAIL_TEMPLATES_COLLECTION_CONFIG,
|
|
8588
8854
|
EMAIL_TEMPLATES_COLLECTION_SLUG,
|
|
8855
|
+
FORM_SHELLS,
|
|
8589
8856
|
FieldConditionBuilder,
|
|
8590
8857
|
ForbiddenError,
|
|
8591
8858
|
INTERNAL_SYSTEM_COLLECTIONS,
|
|
@@ -8624,11 +8891,13 @@ export {
|
|
|
8624
8891
|
clamp,
|
|
8625
8892
|
coalesce,
|
|
8626
8893
|
coerceBooleanWhere,
|
|
8894
|
+
collectAdminComponentsValidationIssues,
|
|
8627
8895
|
collectAdminConditionValidationIssues,
|
|
8628
8896
|
collectConfigDiagnostics,
|
|
8629
8897
|
collectDeclarativeAccessValidationIssues,
|
|
8630
8898
|
collectDeclarativeHookValidationIssues,
|
|
8631
8899
|
collectPreviewUrlValidationIssues,
|
|
8900
|
+
collectReferencedComponentKeys,
|
|
8632
8901
|
compact,
|
|
8633
8902
|
compileNavigation,
|
|
8634
8903
|
count,
|
|
@@ -8649,6 +8918,7 @@ export {
|
|
|
8649
8918
|
defineConfig,
|
|
8650
8919
|
defineCreatedAtField,
|
|
8651
8920
|
defineCreatedByField,
|
|
8921
|
+
defineCustomView,
|
|
8652
8922
|
defineDateField,
|
|
8653
8923
|
defineDateTimeField,
|
|
8654
8924
|
defineEmailField,
|
|
@@ -8664,6 +8934,7 @@ export {
|
|
|
8664
8934
|
defineMultiSelectField,
|
|
8665
8935
|
defineNumberField,
|
|
8666
8936
|
defineObjectField,
|
|
8937
|
+
definePage,
|
|
8667
8938
|
definePublishingWorkflow,
|
|
8668
8939
|
defineRadioField,
|
|
8669
8940
|
defineRelationshipField,
|