@dyrected/core 2.5.60 → 2.5.61
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-config-9hs8DRED.d.cts +1718 -0
- package/dist/app-config-9hs8DRED.d.ts +1718 -0
- package/dist/app-config-C0uxEU7Q.d.cts +1874 -0
- package/dist/app-config-C0uxEU7Q.d.ts +1874 -0
- package/dist/app-config-CBOn8IyZ.d.cts +1838 -0
- package/dist/app-config-CBOn8IyZ.d.ts +1838 -0
- package/dist/app-config-CwaU1de2.d.cts +1868 -0
- package/dist/app-config-CwaU1de2.d.ts +1868 -0
- package/dist/app-config-DVdSospO.d.cts +1842 -0
- package/dist/app-config-DVdSospO.d.ts +1842 -0
- package/dist/app-config-ouBRb6Bf.d.cts +1716 -0
- package/dist/app-config-ouBRb6Bf.d.ts +1716 -0
- package/dist/chunk-35NM2WPO.js +1658 -0
- package/dist/chunk-CUOPCOU2.js +1644 -0
- package/dist/index.cjs +68 -5
- package/dist/index.d.cts +46 -4
- package/dist/index.d.ts +46 -4
- package/dist/index.js +35 -4
- package/dist/server.cjs +44 -5
- package/dist/server.d.cts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +13 -4
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -24,6 +24,7 @@ __export(index_exports, {
|
|
|
24
24
|
LIFECYCLE_EVENT_NAMES: () => LIFECYCLE_EVENT_NAMES,
|
|
25
25
|
WORKFLOW_HISTORY_COLLECTION: () => WORKFLOW_HISTORY_COLLECTION,
|
|
26
26
|
availableWorkflowTransitions: () => availableWorkflowTransitions,
|
|
27
|
+
buildSqlOrderBy: () => buildSqlOrderBy,
|
|
27
28
|
canViewWorkflowDraft: () => canViewWorkflowDraft,
|
|
28
29
|
createLifecycleEvent: () => createLifecycleEvent,
|
|
29
30
|
createWorkflowDocument: () => createWorkflowDocument,
|
|
@@ -65,6 +66,7 @@ __export(index_exports, {
|
|
|
65
66
|
initializeWorkflowDocument: () => initializeWorkflowDocument,
|
|
66
67
|
materializeWorkflowDocument: () => materializeWorkflowDocument,
|
|
67
68
|
normalizeConfig: () => normalizeConfig,
|
|
69
|
+
numericFieldNames: () => numericFieldNames,
|
|
68
70
|
parseMongoWhere: () => parseMongoWhere,
|
|
69
71
|
parseSort: () => parseSort,
|
|
70
72
|
parseSqlWhere: () => parseSqlWhere,
|
|
@@ -72,6 +74,7 @@ __export(index_exports, {
|
|
|
72
74
|
resolveAdminAuthCollection: () => resolveAdminAuthCollection,
|
|
73
75
|
runCollectionHooks: () => runCollectionHooks,
|
|
74
76
|
saveWorkflowDraft: () => saveWorkflowDraft,
|
|
77
|
+
simplePublishingWorkflow: () => simplePublishingWorkflow,
|
|
75
78
|
transitionWorkflow: () => transitionWorkflow,
|
|
76
79
|
workflowCapabilities: () => workflowCapabilities
|
|
77
80
|
});
|
|
@@ -110,6 +113,20 @@ function publishingWorkflow() {
|
|
|
110
113
|
]
|
|
111
114
|
};
|
|
112
115
|
}
|
|
116
|
+
function simplePublishingWorkflow() {
|
|
117
|
+
return {
|
|
118
|
+
initialState: "draft",
|
|
119
|
+
draftState: "draft",
|
|
120
|
+
states: [
|
|
121
|
+
{ name: "draft", label: "Draft", color: "neutral" },
|
|
122
|
+
{ name: "published", label: "Published", color: "success", published: true }
|
|
123
|
+
],
|
|
124
|
+
transitions: [
|
|
125
|
+
{ name: "publish", label: "Publish", from: "draft", to: "published" },
|
|
126
|
+
{ name: "unpublish", label: "Unpublish", from: "published", to: "draft", unpublish: true }
|
|
127
|
+
]
|
|
128
|
+
};
|
|
129
|
+
}
|
|
113
130
|
function publicMetadata(meta) {
|
|
114
131
|
const { availableTransitions: _availableTransitions, ...safe } = meta;
|
|
115
132
|
return safe;
|
|
@@ -143,9 +160,23 @@ function initializeWorkflowDocument(data, workflow) {
|
|
|
143
160
|
__workflow: { state: workflow.initialState, revision: 1 }
|
|
144
161
|
};
|
|
145
162
|
}
|
|
163
|
+
function publishedStateName(workflow) {
|
|
164
|
+
return workflow.states.find((state) => state.published)?.name ?? workflow.states[workflow.states.length - 1]?.name ?? workflow.initialState;
|
|
165
|
+
}
|
|
146
166
|
function materializeWorkflowDocument(doc, workflow, user) {
|
|
147
167
|
const meta = doc.__workflow;
|
|
148
|
-
if (!meta)
|
|
168
|
+
if (!meta) {
|
|
169
|
+
const { __published: _legacyPublished, __workflow: _legacyWorkflow, ...working2 } = doc;
|
|
170
|
+
const state = publishedStateName(workflow);
|
|
171
|
+
return {
|
|
172
|
+
...working2,
|
|
173
|
+
_workflow: {
|
|
174
|
+
state,
|
|
175
|
+
revision: 1,
|
|
176
|
+
availableTransitions: availableWorkflowTransitions(workflow, state, user).map((item) => item.name)
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
}
|
|
149
180
|
const { __published, __workflow, ...working } = doc;
|
|
150
181
|
if (!canViewWorkflowDraft(workflow, user)) {
|
|
151
182
|
if (!__published || typeof __published !== "object") return null;
|
|
@@ -463,7 +494,7 @@ function normalizeConfig(config) {
|
|
|
463
494
|
const collections = config?.collections || [];
|
|
464
495
|
const globals = config?.globals || [];
|
|
465
496
|
const needsAudit = collections.some((col) => col.audit);
|
|
466
|
-
const needsWorkflow = collections.some((col) => col.workflow);
|
|
497
|
+
const needsWorkflow = collections.some((col) => col.workflow || col.drafts);
|
|
467
498
|
const adminAuthCollectionSlug = getAdminAuthCollection({
|
|
468
499
|
collections,
|
|
469
500
|
adminAuth: config.adminAuth
|
|
@@ -598,8 +629,10 @@ function normalizeConfig(config) {
|
|
|
598
629
|
}
|
|
599
630
|
const updatedFieldNames = new Set(fields.map((f) => f.name));
|
|
600
631
|
const fieldsToInject = SYSTEM_FIELDS.filter((f) => !updatedFieldNames.has(f.name));
|
|
632
|
+
const workflow = col.workflow || (col.drafts ? simplePublishingWorkflow() : void 0);
|
|
601
633
|
return {
|
|
602
634
|
...col,
|
|
635
|
+
workflow,
|
|
603
636
|
fields: [...fields, ...fieldsToInject]
|
|
604
637
|
};
|
|
605
638
|
});
|
|
@@ -623,7 +656,7 @@ function normalizeConfig(config) {
|
|
|
623
656
|
function assertNever(op, context) {
|
|
624
657
|
throw new Error(`[dyrected/core] Unhandled where operator "${op}" in ${context}`);
|
|
625
658
|
}
|
|
626
|
-
function parseSqlWhere(where, getJsonField, placeholder = "?") {
|
|
659
|
+
function parseSqlWhere(where, getJsonField, placeholder = "?", likeOperator = "LIKE") {
|
|
627
660
|
const params = [];
|
|
628
661
|
let pgIndex = 1;
|
|
629
662
|
function next() {
|
|
@@ -685,10 +718,10 @@ function parseSqlWhere(where, getJsonField, placeholder = "?") {
|
|
|
685
718
|
return `${c} <= ${next()}`;
|
|
686
719
|
case "contains":
|
|
687
720
|
params.push(`%${operand}%`);
|
|
688
|
-
return `${c}
|
|
721
|
+
return `${c} ${likeOperator} ${next()}`;
|
|
689
722
|
case "starts_with":
|
|
690
723
|
params.push(`${operand}%`);
|
|
691
|
-
return `${c}
|
|
724
|
+
return `${c} ${likeOperator} ${next()}`;
|
|
692
725
|
case "exists":
|
|
693
726
|
return operand ? `${c} IS NOT NULL` : `${c} IS NULL`;
|
|
694
727
|
default:
|
|
@@ -793,6 +826,33 @@ function parseSort(sort, fallback = { field: "createdAt", direction: "DESC" }) {
|
|
|
793
826
|
}).filter((clause) => Boolean(clause));
|
|
794
827
|
return clauses.length > 0 ? clauses : [fallback];
|
|
795
828
|
}
|
|
829
|
+
function numericFieldNames(fields) {
|
|
830
|
+
const names = /* @__PURE__ */ new Set();
|
|
831
|
+
for (const field of fields ?? []) {
|
|
832
|
+
if (field.type === "number" && "name" in field && field.name) {
|
|
833
|
+
names.add(field.name);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
return names;
|
|
837
|
+
}
|
|
838
|
+
var TIMESTAMP_COLUMNS = {
|
|
839
|
+
createdat: "created_at",
|
|
840
|
+
created_at: "created_at",
|
|
841
|
+
updatedat: "updated_at",
|
|
842
|
+
updated_at: "updated_at"
|
|
843
|
+
};
|
|
844
|
+
function buildSqlOrderBy(sort, existingColumns, numericFields, dialect) {
|
|
845
|
+
return parseSort(sort).map(({ field, direction }) => {
|
|
846
|
+
const timestamp = TIMESTAMP_COLUMNS[field.toLowerCase()];
|
|
847
|
+
if (timestamp) return `${dialect.quoteIdent(timestamp)} ${direction}`;
|
|
848
|
+
if (existingColumns.includes(field) && field !== "id" && field !== "data") {
|
|
849
|
+
return `${dialect.quoteIdent(field)} ${direction}`;
|
|
850
|
+
}
|
|
851
|
+
const extracted = dialect.jsonExtract(field);
|
|
852
|
+
const expr = numericFields.has(field) ? dialect.castNumeric(extracted) : extracted;
|
|
853
|
+
return `${expr} ${direction}`;
|
|
854
|
+
}).join(", ");
|
|
855
|
+
}
|
|
796
856
|
|
|
797
857
|
// src/utils/hooks.ts
|
|
798
858
|
async function runCollectionHooks(hooks, args, options = {}) {
|
|
@@ -1916,6 +1976,7 @@ function defineTab(args) {
|
|
|
1916
1976
|
LIFECYCLE_EVENT_NAMES,
|
|
1917
1977
|
WORKFLOW_HISTORY_COLLECTION,
|
|
1918
1978
|
availableWorkflowTransitions,
|
|
1979
|
+
buildSqlOrderBy,
|
|
1919
1980
|
canViewWorkflowDraft,
|
|
1920
1981
|
createLifecycleEvent,
|
|
1921
1982
|
createWorkflowDocument,
|
|
@@ -1957,6 +2018,7 @@ function defineTab(args) {
|
|
|
1957
2018
|
initializeWorkflowDocument,
|
|
1958
2019
|
materializeWorkflowDocument,
|
|
1959
2020
|
normalizeConfig,
|
|
2021
|
+
numericFieldNames,
|
|
1960
2022
|
parseMongoWhere,
|
|
1961
2023
|
parseSort,
|
|
1962
2024
|
parseSqlWhere,
|
|
@@ -1964,6 +2026,7 @@ function defineTab(args) {
|
|
|
1964
2026
|
resolveAdminAuthCollection,
|
|
1965
2027
|
runCollectionHooks,
|
|
1966
2028
|
saveWorkflowDraft,
|
|
2029
|
+
simplePublishingWorkflow,
|
|
1967
2030
|
transitionWorkflow,
|
|
1968
2031
|
workflowCapabilities
|
|
1969
2032
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as Field, B as Block, D as DyrectedConfig, C as CollectionConfig, A as AdminAuthConfig, P as PublicAdminAuthConfig, W as WorkflowConfig, a as AuthenticatedUser, b as WorkflowTransition, L as LifecycleEventName, c as LifecycleEvent, d as BaseDocument, H as HookRequestContext, e as ArrayField, f as BlocksField, g as BooleanField, h as DateField, i as DateTimeField, E as EmailField, G as GlobalConfig, I as IconField, j as ImageField, J as JoinField, k as JsonField, M as MultiSelectField, N as NumberField, O as ObjectField, R as RadioField, l as RelationshipField, m as RichTextField, n as RowField, S as SelectField, T as TextField, o as TextareaField, p as TimeField, U as UrlField } from './app-config-
|
|
2
|
-
export { q as AccessFunction, r as AccessFunctionArgs, s as AccessPolicyResolver, t as AccessResult, u as AccessRule, v as AdminAuthAccessResolution, w as AdminAuthClaimMapping, x as AdminAuthMember, y as AdminAuthProvider, z as AdminAuthProviderMembersConfig, K as AdminAuthProvisioningMode, Q as AdminAuthResolveAccessArgs, V as AdminAuthResolvedIdentity, X as AdminConfig, Y as AdminDashboardComponentSlots, Z as AdminIconName, _ as BaseAdminAuthProvider, $ as BaseFieldAdmin, a0 as BlockVariant, a1 as BooleanFieldAdmin, a2 as
|
|
1
|
+
import { F as Field, B as Block, D as DyrectedConfig, C as CollectionConfig, A as AdminAuthConfig, P as PublicAdminAuthConfig, W as WorkflowConfig, a as AuthenticatedUser, b as WorkflowTransition, L as LifecycleEventName, c as LifecycleEvent, d as BaseDocument, H as HookRequestContext, e as ArrayField, f as BlocksField, g as BooleanField, h as DateField, i as DateTimeField, E as EmailField, G as GlobalConfig, I as IconField, j as ImageField, J as JoinField, k as JsonField, M as MultiSelectField, N as NumberField, O as ObjectField, R as RadioField, l as RelationshipField, m as RichTextField, n as RowField, S as SelectField, T as TextField, o as TextareaField, p as TimeField, U as UrlField } from './app-config-C0uxEU7Q.cjs';
|
|
2
|
+
export { q as AccessFunction, r as AccessFunctionArgs, s as AccessPolicyResolver, t as AccessResult, u as AccessRule, v as AdminAuthAccessResolution, w as AdminAuthClaimMapping, x as AdminAuthMember, y as AdminAuthProvider, z as AdminAuthProviderMembersConfig, K as AdminAuthProvisioningMode, Q as AdminAuthResolveAccessArgs, V as AdminAuthResolvedIdentity, X as AdminConfig, Y as AdminDashboardComponentSlots, Z as AdminIconName, _ as BaseAdminAuthProvider, $ as BaseFieldAdmin, a0 as BlockVariant, a1 as BooleanFieldAdmin, a2 as BooleanFormat, a3 as CharacterLimitFieldAdmin, a4 as CharacterLimitFieldConfig, a5 as CollectionAfterChangeHook, a6 as CollectionAfterDeleteHook, a7 as CollectionAfterReadHook, a8 as CollectionAfterTransitionHook, a9 as CollectionBeforeChangeHook, aa as CollectionBeforeDeleteHook, ab as CollectionBeforeReadHook, ac as CollectionBeforeTransitionHook, ad as CollectionListComponentSlots, ae as CustomAdminAuthProvider, af as DatabaseAdapter, ag as DateFieldAdmin, ah as DateFormat, ai as DisplayTone, aj as DynamicOptionItem, ak as DynamicOptionsConfig, al as DynamicOptionsResolver, am as DynamicOptionsResolverArgs, an as EmailFieldAdmin, ao as FieldAdminHooks, ap as FieldAdminOnChangeHook, aq as FieldAdminOnChangeHookArgs, ar as FieldAdminOptionsHook, as as FieldAdminOptionsHookArgs, at as FieldAdminOptionsHookResult, au as FieldAfterReadHook, av as FieldAfterReadHookArgs, aw as FieldBase, ax as FieldBeforeChangeHook, ay as FieldBeforeChangeHookArgs, az as FieldHook, aA as FieldHooks, aB as FieldType, aC as FileData, aD as GlobalAfterChangeHook, aE as GlobalAfterReadHook, aF as GlobalBeforeChangeHook, aG as GlobalBeforeReadHook, aH as HeadingLevel, aI as HookFunction, aJ as IconFieldAdmin, aK as ImageService, aL as JsonFieldAdmin, aM as JsonFormat, aN as LIFECYCLE_EVENT_NAMES, aO as LifecycleEventHandler, aP as LinkFormat, aQ as MultiSelectFieldAdmin, aR as NamedAccessPolicy, aS as NumberFieldAdmin, aT as NumberFormat, aU as NumberLimitFieldAdmin, aV as NumberLimitFieldConfig, aW as OIDCAdminAuthProvider, aX as OptionFormat, aY as PaginatedResult, aZ as PublicAdminAuthProvider, a_ as RadioFieldAdmin, a$ as ReadonlyDatabaseAdapter, b0 as RichTextFeature, b1 as RichTextFieldConfig, b2 as SelectFieldAdmin, b3 as StorageAdapter, b4 as TextFieldAdmin, b5 as TextFormat, b6 as TextareaFieldAdmin, b7 as TypedField, b8 as UploadConfig, b9 as UrlFieldAdmin, ba as UrlLinkValue, bb as WordLimitFieldAdmin, bc as WordLimitFieldConfig, bd as WorkflowMetadata, be as WorkflowRole, bf as WorkflowState, bg as WorkflowTransitionContext } from './app-config-C0uxEU7Q.cjs';
|
|
3
3
|
import 'lucide-react';
|
|
4
4
|
|
|
5
5
|
type Prettify<T> = {
|
|
@@ -140,7 +140,13 @@ interface SqlWhereResult {
|
|
|
140
140
|
* MySQL: (f) => `JSON_UNQUOTE(JSON_EXTRACT(data, '$.${f}'))`
|
|
141
141
|
* @param placeholder '?' for SQLite/MySQL, 'pg' for auto-incrementing Postgres $1/$2/…
|
|
142
142
|
*/
|
|
143
|
-
declare function parseSqlWhere(where: WhereClause, getJsonField: (field: string) => string, placeholder?: '?' | 'pg'
|
|
143
|
+
declare function parseSqlWhere(where: WhereClause, getJsonField: (field: string) => string, placeholder?: '?' | 'pg',
|
|
144
|
+
/**
|
|
145
|
+
* SQL keyword used for `contains`/`starts_with`. Postgres `LIKE` is
|
|
146
|
+
* case-sensitive, so the Postgres adapter passes `'ILIKE'` to keep substring
|
|
147
|
+
* matching case-insensitive like SQLite and MySQL.
|
|
148
|
+
*/
|
|
149
|
+
likeOperator?: 'LIKE' | 'ILIKE'): SqlWhereResult;
|
|
144
150
|
/**
|
|
145
151
|
* Translates a WhereClause into a MongoDB filter object.
|
|
146
152
|
* Handles nested OR/AND via $or/$and, and all operators via $eq/$in/$gt etc.
|
|
@@ -153,6 +159,41 @@ interface SortClause {
|
|
|
153
159
|
direction: SortDirection;
|
|
154
160
|
}
|
|
155
161
|
declare function parseSort(sort: string | undefined, fallback?: SortClause): SortClause[];
|
|
162
|
+
/**
|
|
163
|
+
* Collects the names of top-level fields declared as numbers. SQL adapters use
|
|
164
|
+
* this to decide which JSON-extracted sort fields need a numeric cast.
|
|
165
|
+
*/
|
|
166
|
+
declare function numericFieldNames(fields?: Field[]): Set<string>;
|
|
167
|
+
/**
|
|
168
|
+
* Dialect hooks for turning a parsed sort into a SQL `ORDER BY` body.
|
|
169
|
+
* Each SQL adapter supplies its own quoting, JSON extraction, and numeric cast.
|
|
170
|
+
*/
|
|
171
|
+
interface SqlSortDialect {
|
|
172
|
+
/** Quote a real column identifier (e.g. `"created_at"` or \`created_at\`). */
|
|
173
|
+
quoteIdent: (identifier: string) => string;
|
|
174
|
+
/** SQL expression that reads a top-level field out of the JSON `data` column. */
|
|
175
|
+
jsonExtract: (field: string) => string;
|
|
176
|
+
/**
|
|
177
|
+
* Wrap a JSON-extracted expression so it sorts numerically instead of
|
|
178
|
+
* lexicographically. Adapters whose JSON extraction already preserves number
|
|
179
|
+
* types (SQLite) can return the expression unchanged.
|
|
180
|
+
*/
|
|
181
|
+
castNumeric: (expr: string) => string;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Builds the `ORDER BY` body shared by the SQL adapters.
|
|
185
|
+
*
|
|
186
|
+
* Real (promoted) columns and the `created_at`/`updated_at` timestamps are
|
|
187
|
+
* ordered by their typed column directly. Everything else is read out of the
|
|
188
|
+
* JSON `data` column — and when a field is declared as a `number`, its extracted
|
|
189
|
+
* value is cast so it orders by magnitude rather than as text ("9" < "10").
|
|
190
|
+
*
|
|
191
|
+
* @param sort The raw sort string (e.g. `"-createdAt"`, `"priority,-views"`).
|
|
192
|
+
* @param existingColumns Real column names present on the table.
|
|
193
|
+
* @param numericFields Names of top-level fields declared with `type: 'number'`.
|
|
194
|
+
* @param dialect Adapter-specific quoting, extraction, and numeric cast.
|
|
195
|
+
*/
|
|
196
|
+
declare function buildSqlOrderBy(sort: string | undefined, existingColumns: string[], numericFields: Set<string>, dialect: SqlSortDialect): string;
|
|
156
197
|
|
|
157
198
|
type AnyHookFn = (args: any) => any;
|
|
158
199
|
/**
|
|
@@ -201,6 +242,7 @@ declare function generateOpenApi(config: DyrectedConfig): any;
|
|
|
201
242
|
declare const WORKFLOW_HISTORY_COLLECTION = "__workflow_history";
|
|
202
243
|
declare const LIFECYCLE_EVENTS_COLLECTION = "__lifecycle_events";
|
|
203
244
|
declare function publishingWorkflow(): WorkflowConfig;
|
|
245
|
+
declare function simplePublishingWorkflow(): WorkflowConfig;
|
|
204
246
|
declare function workflowCapabilities(workflow: WorkflowConfig, user?: AuthenticatedUser): Set<string>;
|
|
205
247
|
declare function canViewWorkflowDraft(workflow: WorkflowConfig, user?: AuthenticatedUser): boolean;
|
|
206
248
|
declare function availableWorkflowTransitions(workflow: WorkflowConfig, state: string, user?: AuthenticatedUser): WorkflowTransition[];
|
|
@@ -497,4 +539,4 @@ declare function defineTab<const T extends readonly Field[]>(args: {
|
|
|
497
539
|
fields: T;
|
|
498
540
|
}): T;
|
|
499
541
|
|
|
500
|
-
export { AdminAuthConfig, ArrayField, type AuthDocFields, AuthenticatedUser, BaseDocument, Block, BlocksField, BooleanField, CollectionConfig, DateField, DateTimeField, DyrectedConfig, EmailField, Field, GlobalConfig, HookRequestContext, IconField, ImageField, type InferDocShape, JoinField, JsonField, LIFECYCLE_EVENTS_COLLECTION, LifecycleEvent, LifecycleEventName, MultiSelectField, NumberField, ObjectField, type Prettify, PublicAdminAuthConfig, RadioField, RelationshipField, RichTextField, RowField, SelectField, type SortClause, type SortDirection, type SqlWhereResult, type SystemDocFields, TextField, TextareaField, TimeField, type UploadDocFields, UrlField, WORKFLOW_HISTORY_COLLECTION, type WhereClause, type WhereOperator, type WhereOperatorName, WorkflowConfig, WorkflowTransition, availableWorkflowTransitions, canViewWorkflowDraft, createLifecycleEvent, createWorkflowDocument, defineArrayField, defineBlock, defineBlocksField, defineBooleanField, defineCollection, defineConfig, defineDateField, defineDateTimeField, defineEmailField, defineField, defineGlobal, defineIconField, defineImageField, defineJoinField, defineJsonField, defineMultiSelectField, defineNumberField, defineObjectField, defineRadioField, defineRelationshipField, defineRichTextField, defineRowField, defineSelectField, defineTab, defineTextField, defineTextareaField, defineTimeField, defineUrlField, dispatchLifecycleEvent, dispatchPendingLifecycleEvents, executeFieldAfterRead, executeFieldBeforeChange, generateOpenApi, getAdminAuthCollection, getPublicAdminAuthConfig, initializeWorkflowDocument, materializeWorkflowDocument, normalizeConfig, parseMongoWhere, parseSort, parseSqlWhere, publishingWorkflow, resolveAdminAuthCollection, runCollectionHooks, saveWorkflowDraft, transitionWorkflow, workflowCapabilities };
|
|
542
|
+
export { AdminAuthConfig, ArrayField, type AuthDocFields, AuthenticatedUser, BaseDocument, Block, BlocksField, BooleanField, CollectionConfig, DateField, DateTimeField, DyrectedConfig, EmailField, Field, GlobalConfig, HookRequestContext, IconField, ImageField, type InferDocShape, JoinField, JsonField, LIFECYCLE_EVENTS_COLLECTION, LifecycleEvent, LifecycleEventName, MultiSelectField, NumberField, ObjectField, type Prettify, PublicAdminAuthConfig, RadioField, RelationshipField, RichTextField, RowField, SelectField, type SortClause, type SortDirection, type SqlSortDialect, type SqlWhereResult, type SystemDocFields, TextField, TextareaField, TimeField, type UploadDocFields, UrlField, WORKFLOW_HISTORY_COLLECTION, type WhereClause, type WhereOperator, type WhereOperatorName, WorkflowConfig, WorkflowTransition, availableWorkflowTransitions, buildSqlOrderBy, canViewWorkflowDraft, createLifecycleEvent, createWorkflowDocument, defineArrayField, defineBlock, defineBlocksField, defineBooleanField, defineCollection, defineConfig, defineDateField, defineDateTimeField, defineEmailField, defineField, defineGlobal, defineIconField, defineImageField, defineJoinField, defineJsonField, defineMultiSelectField, defineNumberField, defineObjectField, defineRadioField, defineRelationshipField, defineRichTextField, defineRowField, defineSelectField, defineTab, defineTextField, defineTextareaField, defineTimeField, defineUrlField, dispatchLifecycleEvent, dispatchPendingLifecycleEvents, executeFieldAfterRead, executeFieldBeforeChange, generateOpenApi, getAdminAuthCollection, getPublicAdminAuthConfig, initializeWorkflowDocument, materializeWorkflowDocument, normalizeConfig, numericFieldNames, parseMongoWhere, parseSort, parseSqlWhere, publishingWorkflow, resolveAdminAuthCollection, runCollectionHooks, saveWorkflowDraft, simplePublishingWorkflow, transitionWorkflow, workflowCapabilities };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as Field, B as Block, D as DyrectedConfig, C as CollectionConfig, A as AdminAuthConfig, P as PublicAdminAuthConfig, W as WorkflowConfig, a as AuthenticatedUser, b as WorkflowTransition, L as LifecycleEventName, c as LifecycleEvent, d as BaseDocument, H as HookRequestContext, e as ArrayField, f as BlocksField, g as BooleanField, h as DateField, i as DateTimeField, E as EmailField, G as GlobalConfig, I as IconField, j as ImageField, J as JoinField, k as JsonField, M as MultiSelectField, N as NumberField, O as ObjectField, R as RadioField, l as RelationshipField, m as RichTextField, n as RowField, S as SelectField, T as TextField, o as TextareaField, p as TimeField, U as UrlField } from './app-config-
|
|
2
|
-
export { q as AccessFunction, r as AccessFunctionArgs, s as AccessPolicyResolver, t as AccessResult, u as AccessRule, v as AdminAuthAccessResolution, w as AdminAuthClaimMapping, x as AdminAuthMember, y as AdminAuthProvider, z as AdminAuthProviderMembersConfig, K as AdminAuthProvisioningMode, Q as AdminAuthResolveAccessArgs, V as AdminAuthResolvedIdentity, X as AdminConfig, Y as AdminDashboardComponentSlots, Z as AdminIconName, _ as BaseAdminAuthProvider, $ as BaseFieldAdmin, a0 as BlockVariant, a1 as BooleanFieldAdmin, a2 as
|
|
1
|
+
import { F as Field, B as Block, D as DyrectedConfig, C as CollectionConfig, A as AdminAuthConfig, P as PublicAdminAuthConfig, W as WorkflowConfig, a as AuthenticatedUser, b as WorkflowTransition, L as LifecycleEventName, c as LifecycleEvent, d as BaseDocument, H as HookRequestContext, e as ArrayField, f as BlocksField, g as BooleanField, h as DateField, i as DateTimeField, E as EmailField, G as GlobalConfig, I as IconField, j as ImageField, J as JoinField, k as JsonField, M as MultiSelectField, N as NumberField, O as ObjectField, R as RadioField, l as RelationshipField, m as RichTextField, n as RowField, S as SelectField, T as TextField, o as TextareaField, p as TimeField, U as UrlField } from './app-config-C0uxEU7Q.js';
|
|
2
|
+
export { q as AccessFunction, r as AccessFunctionArgs, s as AccessPolicyResolver, t as AccessResult, u as AccessRule, v as AdminAuthAccessResolution, w as AdminAuthClaimMapping, x as AdminAuthMember, y as AdminAuthProvider, z as AdminAuthProviderMembersConfig, K as AdminAuthProvisioningMode, Q as AdminAuthResolveAccessArgs, V as AdminAuthResolvedIdentity, X as AdminConfig, Y as AdminDashboardComponentSlots, Z as AdminIconName, _ as BaseAdminAuthProvider, $ as BaseFieldAdmin, a0 as BlockVariant, a1 as BooleanFieldAdmin, a2 as BooleanFormat, a3 as CharacterLimitFieldAdmin, a4 as CharacterLimitFieldConfig, a5 as CollectionAfterChangeHook, a6 as CollectionAfterDeleteHook, a7 as CollectionAfterReadHook, a8 as CollectionAfterTransitionHook, a9 as CollectionBeforeChangeHook, aa as CollectionBeforeDeleteHook, ab as CollectionBeforeReadHook, ac as CollectionBeforeTransitionHook, ad as CollectionListComponentSlots, ae as CustomAdminAuthProvider, af as DatabaseAdapter, ag as DateFieldAdmin, ah as DateFormat, ai as DisplayTone, aj as DynamicOptionItem, ak as DynamicOptionsConfig, al as DynamicOptionsResolver, am as DynamicOptionsResolverArgs, an as EmailFieldAdmin, ao as FieldAdminHooks, ap as FieldAdminOnChangeHook, aq as FieldAdminOnChangeHookArgs, ar as FieldAdminOptionsHook, as as FieldAdminOptionsHookArgs, at as FieldAdminOptionsHookResult, au as FieldAfterReadHook, av as FieldAfterReadHookArgs, aw as FieldBase, ax as FieldBeforeChangeHook, ay as FieldBeforeChangeHookArgs, az as FieldHook, aA as FieldHooks, aB as FieldType, aC as FileData, aD as GlobalAfterChangeHook, aE as GlobalAfterReadHook, aF as GlobalBeforeChangeHook, aG as GlobalBeforeReadHook, aH as HeadingLevel, aI as HookFunction, aJ as IconFieldAdmin, aK as ImageService, aL as JsonFieldAdmin, aM as JsonFormat, aN as LIFECYCLE_EVENT_NAMES, aO as LifecycleEventHandler, aP as LinkFormat, aQ as MultiSelectFieldAdmin, aR as NamedAccessPolicy, aS as NumberFieldAdmin, aT as NumberFormat, aU as NumberLimitFieldAdmin, aV as NumberLimitFieldConfig, aW as OIDCAdminAuthProvider, aX as OptionFormat, aY as PaginatedResult, aZ as PublicAdminAuthProvider, a_ as RadioFieldAdmin, a$ as ReadonlyDatabaseAdapter, b0 as RichTextFeature, b1 as RichTextFieldConfig, b2 as SelectFieldAdmin, b3 as StorageAdapter, b4 as TextFieldAdmin, b5 as TextFormat, b6 as TextareaFieldAdmin, b7 as TypedField, b8 as UploadConfig, b9 as UrlFieldAdmin, ba as UrlLinkValue, bb as WordLimitFieldAdmin, bc as WordLimitFieldConfig, bd as WorkflowMetadata, be as WorkflowRole, bf as WorkflowState, bg as WorkflowTransitionContext } from './app-config-C0uxEU7Q.js';
|
|
3
3
|
import 'lucide-react';
|
|
4
4
|
|
|
5
5
|
type Prettify<T> = {
|
|
@@ -140,7 +140,13 @@ interface SqlWhereResult {
|
|
|
140
140
|
* MySQL: (f) => `JSON_UNQUOTE(JSON_EXTRACT(data, '$.${f}'))`
|
|
141
141
|
* @param placeholder '?' for SQLite/MySQL, 'pg' for auto-incrementing Postgres $1/$2/…
|
|
142
142
|
*/
|
|
143
|
-
declare function parseSqlWhere(where: WhereClause, getJsonField: (field: string) => string, placeholder?: '?' | 'pg'
|
|
143
|
+
declare function parseSqlWhere(where: WhereClause, getJsonField: (field: string) => string, placeholder?: '?' | 'pg',
|
|
144
|
+
/**
|
|
145
|
+
* SQL keyword used for `contains`/`starts_with`. Postgres `LIKE` is
|
|
146
|
+
* case-sensitive, so the Postgres adapter passes `'ILIKE'` to keep substring
|
|
147
|
+
* matching case-insensitive like SQLite and MySQL.
|
|
148
|
+
*/
|
|
149
|
+
likeOperator?: 'LIKE' | 'ILIKE'): SqlWhereResult;
|
|
144
150
|
/**
|
|
145
151
|
* Translates a WhereClause into a MongoDB filter object.
|
|
146
152
|
* Handles nested OR/AND via $or/$and, and all operators via $eq/$in/$gt etc.
|
|
@@ -153,6 +159,41 @@ interface SortClause {
|
|
|
153
159
|
direction: SortDirection;
|
|
154
160
|
}
|
|
155
161
|
declare function parseSort(sort: string | undefined, fallback?: SortClause): SortClause[];
|
|
162
|
+
/**
|
|
163
|
+
* Collects the names of top-level fields declared as numbers. SQL adapters use
|
|
164
|
+
* this to decide which JSON-extracted sort fields need a numeric cast.
|
|
165
|
+
*/
|
|
166
|
+
declare function numericFieldNames(fields?: Field[]): Set<string>;
|
|
167
|
+
/**
|
|
168
|
+
* Dialect hooks for turning a parsed sort into a SQL `ORDER BY` body.
|
|
169
|
+
* Each SQL adapter supplies its own quoting, JSON extraction, and numeric cast.
|
|
170
|
+
*/
|
|
171
|
+
interface SqlSortDialect {
|
|
172
|
+
/** Quote a real column identifier (e.g. `"created_at"` or \`created_at\`). */
|
|
173
|
+
quoteIdent: (identifier: string) => string;
|
|
174
|
+
/** SQL expression that reads a top-level field out of the JSON `data` column. */
|
|
175
|
+
jsonExtract: (field: string) => string;
|
|
176
|
+
/**
|
|
177
|
+
* Wrap a JSON-extracted expression so it sorts numerically instead of
|
|
178
|
+
* lexicographically. Adapters whose JSON extraction already preserves number
|
|
179
|
+
* types (SQLite) can return the expression unchanged.
|
|
180
|
+
*/
|
|
181
|
+
castNumeric: (expr: string) => string;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Builds the `ORDER BY` body shared by the SQL adapters.
|
|
185
|
+
*
|
|
186
|
+
* Real (promoted) columns and the `created_at`/`updated_at` timestamps are
|
|
187
|
+
* ordered by their typed column directly. Everything else is read out of the
|
|
188
|
+
* JSON `data` column — and when a field is declared as a `number`, its extracted
|
|
189
|
+
* value is cast so it orders by magnitude rather than as text ("9" < "10").
|
|
190
|
+
*
|
|
191
|
+
* @param sort The raw sort string (e.g. `"-createdAt"`, `"priority,-views"`).
|
|
192
|
+
* @param existingColumns Real column names present on the table.
|
|
193
|
+
* @param numericFields Names of top-level fields declared with `type: 'number'`.
|
|
194
|
+
* @param dialect Adapter-specific quoting, extraction, and numeric cast.
|
|
195
|
+
*/
|
|
196
|
+
declare function buildSqlOrderBy(sort: string | undefined, existingColumns: string[], numericFields: Set<string>, dialect: SqlSortDialect): string;
|
|
156
197
|
|
|
157
198
|
type AnyHookFn = (args: any) => any;
|
|
158
199
|
/**
|
|
@@ -201,6 +242,7 @@ declare function generateOpenApi(config: DyrectedConfig): any;
|
|
|
201
242
|
declare const WORKFLOW_HISTORY_COLLECTION = "__workflow_history";
|
|
202
243
|
declare const LIFECYCLE_EVENTS_COLLECTION = "__lifecycle_events";
|
|
203
244
|
declare function publishingWorkflow(): WorkflowConfig;
|
|
245
|
+
declare function simplePublishingWorkflow(): WorkflowConfig;
|
|
204
246
|
declare function workflowCapabilities(workflow: WorkflowConfig, user?: AuthenticatedUser): Set<string>;
|
|
205
247
|
declare function canViewWorkflowDraft(workflow: WorkflowConfig, user?: AuthenticatedUser): boolean;
|
|
206
248
|
declare function availableWorkflowTransitions(workflow: WorkflowConfig, state: string, user?: AuthenticatedUser): WorkflowTransition[];
|
|
@@ -497,4 +539,4 @@ declare function defineTab<const T extends readonly Field[]>(args: {
|
|
|
497
539
|
fields: T;
|
|
498
540
|
}): T;
|
|
499
541
|
|
|
500
|
-
export { AdminAuthConfig, ArrayField, type AuthDocFields, AuthenticatedUser, BaseDocument, Block, BlocksField, BooleanField, CollectionConfig, DateField, DateTimeField, DyrectedConfig, EmailField, Field, GlobalConfig, HookRequestContext, IconField, ImageField, type InferDocShape, JoinField, JsonField, LIFECYCLE_EVENTS_COLLECTION, LifecycleEvent, LifecycleEventName, MultiSelectField, NumberField, ObjectField, type Prettify, PublicAdminAuthConfig, RadioField, RelationshipField, RichTextField, RowField, SelectField, type SortClause, type SortDirection, type SqlWhereResult, type SystemDocFields, TextField, TextareaField, TimeField, type UploadDocFields, UrlField, WORKFLOW_HISTORY_COLLECTION, type WhereClause, type WhereOperator, type WhereOperatorName, WorkflowConfig, WorkflowTransition, availableWorkflowTransitions, canViewWorkflowDraft, createLifecycleEvent, createWorkflowDocument, defineArrayField, defineBlock, defineBlocksField, defineBooleanField, defineCollection, defineConfig, defineDateField, defineDateTimeField, defineEmailField, defineField, defineGlobal, defineIconField, defineImageField, defineJoinField, defineJsonField, defineMultiSelectField, defineNumberField, defineObjectField, defineRadioField, defineRelationshipField, defineRichTextField, defineRowField, defineSelectField, defineTab, defineTextField, defineTextareaField, defineTimeField, defineUrlField, dispatchLifecycleEvent, dispatchPendingLifecycleEvents, executeFieldAfterRead, executeFieldBeforeChange, generateOpenApi, getAdminAuthCollection, getPublicAdminAuthConfig, initializeWorkflowDocument, materializeWorkflowDocument, normalizeConfig, parseMongoWhere, parseSort, parseSqlWhere, publishingWorkflow, resolveAdminAuthCollection, runCollectionHooks, saveWorkflowDraft, transitionWorkflow, workflowCapabilities };
|
|
542
|
+
export { AdminAuthConfig, ArrayField, type AuthDocFields, AuthenticatedUser, BaseDocument, Block, BlocksField, BooleanField, CollectionConfig, DateField, DateTimeField, DyrectedConfig, EmailField, Field, GlobalConfig, HookRequestContext, IconField, ImageField, type InferDocShape, JoinField, JsonField, LIFECYCLE_EVENTS_COLLECTION, LifecycleEvent, LifecycleEventName, MultiSelectField, NumberField, ObjectField, type Prettify, PublicAdminAuthConfig, RadioField, RelationshipField, RichTextField, RowField, SelectField, type SortClause, type SortDirection, type SqlSortDialect, type SqlWhereResult, type SystemDocFields, TextField, TextareaField, TimeField, type UploadDocFields, UrlField, WORKFLOW_HISTORY_COLLECTION, type WhereClause, type WhereOperator, type WhereOperatorName, WorkflowConfig, WorkflowTransition, availableWorkflowTransitions, buildSqlOrderBy, canViewWorkflowDraft, createLifecycleEvent, createWorkflowDocument, defineArrayField, defineBlock, defineBlocksField, defineBooleanField, defineCollection, defineConfig, defineDateField, defineDateTimeField, defineEmailField, defineField, defineGlobal, defineIconField, defineImageField, defineJoinField, defineJsonField, defineMultiSelectField, defineNumberField, defineObjectField, defineRadioField, defineRelationshipField, defineRichTextField, defineRowField, defineSelectField, defineTab, defineTextField, defineTextareaField, defineTimeField, defineUrlField, dispatchLifecycleEvent, dispatchPendingLifecycleEvents, executeFieldAfterRead, executeFieldBeforeChange, generateOpenApi, getAdminAuthCollection, getPublicAdminAuthConfig, initializeWorkflowDocument, materializeWorkflowDocument, normalizeConfig, numericFieldNames, parseMongoWhere, parseSort, parseSqlWhere, publishingWorkflow, resolveAdminAuthCollection, runCollectionHooks, saveWorkflowDraft, simplePublishingWorkflow, transitionWorkflow, workflowCapabilities };
|
package/dist/index.js
CHANGED
|
@@ -19,9 +19,10 @@ import {
|
|
|
19
19
|
resolveAdminAuthCollection,
|
|
20
20
|
runCollectionHooks,
|
|
21
21
|
saveWorkflowDraft,
|
|
22
|
+
simplePublishingWorkflow,
|
|
22
23
|
transitionWorkflow,
|
|
23
24
|
workflowCapabilities
|
|
24
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-35NM2WPO.js";
|
|
25
26
|
|
|
26
27
|
// src/types/workflows.ts
|
|
27
28
|
var LIFECYCLE_EVENT_NAMES = [
|
|
@@ -35,7 +36,7 @@ var LIFECYCLE_EVENT_NAMES = [
|
|
|
35
36
|
function assertNever(op, context) {
|
|
36
37
|
throw new Error(`[dyrected/core] Unhandled where operator "${op}" in ${context}`);
|
|
37
38
|
}
|
|
38
|
-
function parseSqlWhere(where, getJsonField, placeholder = "?") {
|
|
39
|
+
function parseSqlWhere(where, getJsonField, placeholder = "?", likeOperator = "LIKE") {
|
|
39
40
|
const params = [];
|
|
40
41
|
let pgIndex = 1;
|
|
41
42
|
function next() {
|
|
@@ -97,10 +98,10 @@ function parseSqlWhere(where, getJsonField, placeholder = "?") {
|
|
|
97
98
|
return `${c} <= ${next()}`;
|
|
98
99
|
case "contains":
|
|
99
100
|
params.push(`%${operand}%`);
|
|
100
|
-
return `${c}
|
|
101
|
+
return `${c} ${likeOperator} ${next()}`;
|
|
101
102
|
case "starts_with":
|
|
102
103
|
params.push(`${operand}%`);
|
|
103
|
-
return `${c}
|
|
104
|
+
return `${c} ${likeOperator} ${next()}`;
|
|
104
105
|
case "exists":
|
|
105
106
|
return operand ? `${c} IS NOT NULL` : `${c} IS NULL`;
|
|
106
107
|
default:
|
|
@@ -205,6 +206,33 @@ function parseSort(sort, fallback = { field: "createdAt", direction: "DESC" }) {
|
|
|
205
206
|
}).filter((clause) => Boolean(clause));
|
|
206
207
|
return clauses.length > 0 ? clauses : [fallback];
|
|
207
208
|
}
|
|
209
|
+
function numericFieldNames(fields) {
|
|
210
|
+
const names = /* @__PURE__ */ new Set();
|
|
211
|
+
for (const field of fields ?? []) {
|
|
212
|
+
if (field.type === "number" && "name" in field && field.name) {
|
|
213
|
+
names.add(field.name);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return names;
|
|
217
|
+
}
|
|
218
|
+
var TIMESTAMP_COLUMNS = {
|
|
219
|
+
createdat: "created_at",
|
|
220
|
+
created_at: "created_at",
|
|
221
|
+
updatedat: "updated_at",
|
|
222
|
+
updated_at: "updated_at"
|
|
223
|
+
};
|
|
224
|
+
function buildSqlOrderBy(sort, existingColumns, numericFields, dialect) {
|
|
225
|
+
return parseSort(sort).map(({ field, direction }) => {
|
|
226
|
+
const timestamp = TIMESTAMP_COLUMNS[field.toLowerCase()];
|
|
227
|
+
if (timestamp) return `${dialect.quoteIdent(timestamp)} ${direction}`;
|
|
228
|
+
if (existingColumns.includes(field) && field !== "id" && field !== "data") {
|
|
229
|
+
return `${dialect.quoteIdent(field)} ${direction}`;
|
|
230
|
+
}
|
|
231
|
+
const extracted = dialect.jsonExtract(field);
|
|
232
|
+
const expr = numericFields.has(field) ? dialect.castNumeric(extracted) : extracted;
|
|
233
|
+
return `${expr} ${direction}`;
|
|
234
|
+
}).join(", ");
|
|
235
|
+
}
|
|
208
236
|
|
|
209
237
|
// src/index.ts
|
|
210
238
|
function defineCollection(config) {
|
|
@@ -258,6 +286,7 @@ export {
|
|
|
258
286
|
LIFECYCLE_EVENT_NAMES,
|
|
259
287
|
WORKFLOW_HISTORY_COLLECTION,
|
|
260
288
|
availableWorkflowTransitions,
|
|
289
|
+
buildSqlOrderBy,
|
|
261
290
|
canViewWorkflowDraft,
|
|
262
291
|
createLifecycleEvent,
|
|
263
292
|
createWorkflowDocument,
|
|
@@ -299,6 +328,7 @@ export {
|
|
|
299
328
|
initializeWorkflowDocument,
|
|
300
329
|
materializeWorkflowDocument,
|
|
301
330
|
normalizeConfig,
|
|
331
|
+
numericFieldNames,
|
|
302
332
|
parseMongoWhere,
|
|
303
333
|
parseSort,
|
|
304
334
|
parseSqlWhere,
|
|
@@ -306,6 +336,7 @@ export {
|
|
|
306
336
|
resolveAdminAuthCollection,
|
|
307
337
|
runCollectionHooks,
|
|
308
338
|
saveWorkflowDraft,
|
|
339
|
+
simplePublishingWorkflow,
|
|
309
340
|
transitionWorkflow,
|
|
310
341
|
workflowCapabilities
|
|
311
342
|
};
|
package/dist/server.cjs
CHANGED
|
@@ -827,6 +827,20 @@ function mergeWhereConstraint(where, constraint) {
|
|
|
827
827
|
// src/workflows.ts
|
|
828
828
|
var WORKFLOW_HISTORY_COLLECTION = "__workflow_history";
|
|
829
829
|
var LIFECYCLE_EVENTS_COLLECTION = "__lifecycle_events";
|
|
830
|
+
function simplePublishingWorkflow() {
|
|
831
|
+
return {
|
|
832
|
+
initialState: "draft",
|
|
833
|
+
draftState: "draft",
|
|
834
|
+
states: [
|
|
835
|
+
{ name: "draft", label: "Draft", color: "neutral" },
|
|
836
|
+
{ name: "published", label: "Published", color: "success", published: true }
|
|
837
|
+
],
|
|
838
|
+
transitions: [
|
|
839
|
+
{ name: "publish", label: "Publish", from: "draft", to: "published" },
|
|
840
|
+
{ name: "unpublish", label: "Unpublish", from: "published", to: "draft", unpublish: true }
|
|
841
|
+
]
|
|
842
|
+
};
|
|
843
|
+
}
|
|
830
844
|
function publicMetadata(meta) {
|
|
831
845
|
const { availableTransitions: _availableTransitions, ...safe } = meta;
|
|
832
846
|
return safe;
|
|
@@ -860,9 +874,23 @@ function initializeWorkflowDocument(data, workflow) {
|
|
|
860
874
|
__workflow: { state: workflow.initialState, revision: 1 }
|
|
861
875
|
};
|
|
862
876
|
}
|
|
877
|
+
function publishedStateName(workflow) {
|
|
878
|
+
return workflow.states.find((state) => state.published)?.name ?? workflow.states[workflow.states.length - 1]?.name ?? workflow.initialState;
|
|
879
|
+
}
|
|
863
880
|
function materializeWorkflowDocument(doc, workflow, user) {
|
|
864
881
|
const meta = doc.__workflow;
|
|
865
|
-
if (!meta)
|
|
882
|
+
if (!meta) {
|
|
883
|
+
const { __published: _legacyPublished, __workflow: _legacyWorkflow, ...working2 } = doc;
|
|
884
|
+
const state = publishedStateName(workflow);
|
|
885
|
+
return {
|
|
886
|
+
...working2,
|
|
887
|
+
_workflow: {
|
|
888
|
+
state,
|
|
889
|
+
revision: 1,
|
|
890
|
+
availableTransitions: availableWorkflowTransitions(workflow, state, user).map((item) => item.name)
|
|
891
|
+
}
|
|
892
|
+
};
|
|
893
|
+
}
|
|
866
894
|
const { __published, __workflow, ...working } = doc;
|
|
867
895
|
if (!canViewWorkflowDraft(workflow, user)) {
|
|
868
896
|
if (!__published || typeof __published !== "object") return null;
|
|
@@ -1122,7 +1150,7 @@ var CollectionController = class {
|
|
|
1122
1150
|
});
|
|
1123
1151
|
}
|
|
1124
1152
|
const readonlyDb = createReadonlyDb(db);
|
|
1125
|
-
const limit = Number(c.req.query("limit")) || 10;
|
|
1153
|
+
const limit = Math.min(Number(c.req.query("limit")) || 10, 100);
|
|
1126
1154
|
const page = Number(c.req.query("page")) || 1;
|
|
1127
1155
|
const depth = c.req.query("depth") !== void 0 ? Number(c.req.query("depth")) : 1;
|
|
1128
1156
|
const sort = c.req.query("sort") || void 0;
|
|
@@ -1170,7 +1198,8 @@ var CollectionController = class {
|
|
|
1170
1198
|
limit,
|
|
1171
1199
|
page,
|
|
1172
1200
|
sort,
|
|
1173
|
-
where
|
|
1201
|
+
where,
|
|
1202
|
+
fields: this.collection.fields
|
|
1174
1203
|
});
|
|
1175
1204
|
if (result.total === 0 && this.collection.initialData && !where && page === 1) {
|
|
1176
1205
|
console.log(`[dyrected/core] Auto-seeding collection "${this.collection.slug}" from config.initialData`);
|
|
@@ -1182,7 +1211,8 @@ var CollectionController = class {
|
|
|
1182
1211
|
limit,
|
|
1183
1212
|
page,
|
|
1184
1213
|
sort,
|
|
1185
|
-
where
|
|
1214
|
+
where,
|
|
1215
|
+
fields: this.collection.fields
|
|
1186
1216
|
});
|
|
1187
1217
|
}
|
|
1188
1218
|
result.docs = result.docs.map((doc) => this.collection.workflow ? materializeWorkflowDocument(doc, this.collection.workflow, user) : doc).filter((doc) => doc !== null);
|
|
@@ -4352,6 +4382,8 @@ function registerRoutes(app, config) {
|
|
|
4352
4382
|
}))),
|
|
4353
4383
|
upload: !!col.upload,
|
|
4354
4384
|
auth: !!col.auth,
|
|
4385
|
+
audit: !!col.audit,
|
|
4386
|
+
drafts: !!col.drafts,
|
|
4355
4387
|
admin: col.admin,
|
|
4356
4388
|
workflow: col.workflow ? {
|
|
4357
4389
|
initialState: col.workflow.initialState,
|
|
@@ -4672,6 +4704,11 @@ function registerRoutes(app, config) {
|
|
|
4672
4704
|
app.patch(path, (c) => controller.update(c));
|
|
4673
4705
|
app.post(`${path}/seed`, (c) => controller.seed(c));
|
|
4674
4706
|
}
|
|
4707
|
+
if (!process.env.DYRECTED_JWT_SECRET) {
|
|
4708
|
+
console.warn(
|
|
4709
|
+
'[dyrected] DYRECTED_JWT_SECRET is not set \u2014 token-mode live preview is signing with an insecure default. Set DYRECTED_JWT_SECRET before relying on `previewMode: "token"` in production.'
|
|
4710
|
+
);
|
|
4711
|
+
}
|
|
4675
4712
|
const previewController = new PreviewController();
|
|
4676
4713
|
app.post("/api/preview-token", requireAuth(config), (c) => previewController.createToken(c));
|
|
4677
4714
|
app.get("/api/preview-data", (c) => previewController.getData(c));
|
|
@@ -4884,7 +4921,7 @@ function normalizeConfig(config) {
|
|
|
4884
4921
|
const collections = config?.collections || [];
|
|
4885
4922
|
const globals = config?.globals || [];
|
|
4886
4923
|
const needsAudit = collections.some((col) => col.audit);
|
|
4887
|
-
const needsWorkflow = collections.some((col) => col.workflow);
|
|
4924
|
+
const needsWorkflow = collections.some((col) => col.workflow || col.drafts);
|
|
4888
4925
|
const adminAuthCollectionSlug = getAdminAuthCollection({
|
|
4889
4926
|
collections,
|
|
4890
4927
|
adminAuth: config.adminAuth
|
|
@@ -5019,8 +5056,10 @@ function normalizeConfig(config) {
|
|
|
5019
5056
|
}
|
|
5020
5057
|
const updatedFieldNames = new Set(fields.map((f) => f.name));
|
|
5021
5058
|
const fieldsToInject = SYSTEM_FIELDS.filter((f) => !updatedFieldNames.has(f.name));
|
|
5059
|
+
const workflow = col.workflow || (col.drafts ? simplePublishingWorkflow() : void 0);
|
|
5022
5060
|
return {
|
|
5023
5061
|
...col,
|
|
5062
|
+
workflow,
|
|
5024
5063
|
fields: [...fields, ...fieldsToInject]
|
|
5025
5064
|
};
|
|
5026
5065
|
});
|
package/dist/server.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as hono_types from 'hono/types';
|
|
2
2
|
import * as hono from 'hono';
|
|
3
3
|
import { Hono, Context } from 'hono';
|
|
4
|
-
import { D as DyrectedConfig, C as CollectionConfig, G as GlobalConfig } from './app-config-
|
|
4
|
+
import { D as DyrectedConfig, C as CollectionConfig, G as GlobalConfig } from './app-config-C0uxEU7Q.cjs';
|
|
5
5
|
import * as hono_utils_http_status from 'hono/utils/http-status';
|
|
6
6
|
import * as hono_utils_types from 'hono/utils/types';
|
|
7
7
|
import 'lucide-react';
|
package/dist/server.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as hono_types from 'hono/types';
|
|
2
2
|
import * as hono from 'hono';
|
|
3
3
|
import { Hono, Context } from 'hono';
|
|
4
|
-
import { D as DyrectedConfig, C as CollectionConfig, G as GlobalConfig } from './app-config-
|
|
4
|
+
import { D as DyrectedConfig, C as CollectionConfig, G as GlobalConfig } from './app-config-C0uxEU7Q.js';
|
|
5
5
|
import * as hono_utils_http_status from 'hono/utils/http-status';
|
|
6
6
|
import * as hono_utils_types from 'hono/utils/types';
|
|
7
7
|
import 'lucide-react';
|
package/dist/server.js
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
runCollectionHooks,
|
|
14
14
|
saveWorkflowDraft,
|
|
15
15
|
transitionWorkflow
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-35NM2WPO.js";
|
|
17
17
|
|
|
18
18
|
// src/app.ts
|
|
19
19
|
import { Hono } from "hono";
|
|
@@ -611,7 +611,7 @@ var CollectionController = class {
|
|
|
611
611
|
});
|
|
612
612
|
}
|
|
613
613
|
const readonlyDb = createReadonlyDb(db);
|
|
614
|
-
const limit = Number(c.req.query("limit")) || 10;
|
|
614
|
+
const limit = Math.min(Number(c.req.query("limit")) || 10, 100);
|
|
615
615
|
const page = Number(c.req.query("page")) || 1;
|
|
616
616
|
const depth = c.req.query("depth") !== void 0 ? Number(c.req.query("depth")) : 1;
|
|
617
617
|
const sort = c.req.query("sort") || void 0;
|
|
@@ -659,7 +659,8 @@ var CollectionController = class {
|
|
|
659
659
|
limit,
|
|
660
660
|
page,
|
|
661
661
|
sort,
|
|
662
|
-
where
|
|
662
|
+
where,
|
|
663
|
+
fields: this.collection.fields
|
|
663
664
|
});
|
|
664
665
|
if (result.total === 0 && this.collection.initialData && !where && page === 1) {
|
|
665
666
|
console.log(`[dyrected/core] Auto-seeding collection "${this.collection.slug}" from config.initialData`);
|
|
@@ -671,7 +672,8 @@ var CollectionController = class {
|
|
|
671
672
|
limit,
|
|
672
673
|
page,
|
|
673
674
|
sort,
|
|
674
|
-
where
|
|
675
|
+
where,
|
|
676
|
+
fields: this.collection.fields
|
|
675
677
|
});
|
|
676
678
|
}
|
|
677
679
|
result.docs = result.docs.map((doc) => this.collection.workflow ? materializeWorkflowDocument(doc, this.collection.workflow, user) : doc).filter((doc) => doc !== null);
|
|
@@ -2940,6 +2942,8 @@ function registerRoutes(app, config) {
|
|
|
2940
2942
|
}))),
|
|
2941
2943
|
upload: !!col.upload,
|
|
2942
2944
|
auth: !!col.auth,
|
|
2945
|
+
audit: !!col.audit,
|
|
2946
|
+
drafts: !!col.drafts,
|
|
2943
2947
|
admin: col.admin,
|
|
2944
2948
|
workflow: col.workflow ? {
|
|
2945
2949
|
initialState: col.workflow.initialState,
|
|
@@ -3260,6 +3264,11 @@ function registerRoutes(app, config) {
|
|
|
3260
3264
|
app.patch(path, (c) => controller.update(c));
|
|
3261
3265
|
app.post(`${path}/seed`, (c) => controller.seed(c));
|
|
3262
3266
|
}
|
|
3267
|
+
if (!process.env.DYRECTED_JWT_SECRET) {
|
|
3268
|
+
console.warn(
|
|
3269
|
+
'[dyrected] DYRECTED_JWT_SECRET is not set \u2014 token-mode live preview is signing with an insecure default. Set DYRECTED_JWT_SECRET before relying on `previewMode: "token"` in production.'
|
|
3270
|
+
);
|
|
3271
|
+
}
|
|
3263
3272
|
const previewController = new PreviewController();
|
|
3264
3273
|
app.post("/api/preview-token", requireAuth(config), (c) => previewController.createToken(c));
|
|
3265
3274
|
app.get("/api/preview-data", (c) => previewController.getData(c));
|