@nexpress/core 0.3.2 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-ANZBCOEH.js → chunk-AYWEGNEX.js} +6 -6
- package/dist/{chunk-P5WGQRSG.js → chunk-EFZH6UPY.js} +5 -2
- package/dist/chunk-EFZH6UPY.js.map +1 -0
- package/dist/{chunk-54KUQF3S.js → chunk-G5OVHS2V.js} +2 -2
- package/dist/{chunk-M2FWG5OJ.js → chunk-ITJ6DX2L.js} +2 -2
- package/dist/{chunk-C6HXDY46.js → chunk-N3LILW6D.js} +2 -2
- package/dist/{chunk-ZA3IRJUQ.js → chunk-O3YQ5EMA.js} +7 -7
- package/dist/{chunk-YOFCLTBR.js → chunk-ZGPZPMZD.js} +2 -2
- package/dist/community.js +4 -4
- package/dist/{config-O7QM2OQS.js → config-XTLZZTOF.js} +4 -4
- package/dist/fields.js +1 -1
- package/dist/{host-NI3LR774.js → host-DIQNMXIB.js} +3 -3
- package/dist/index.js +7 -7
- package/dist/jobs.js +1 -1
- package/dist/{scheduled-BWJG35Z2.js → scheduled-4T3QXV7A.js} +4 -4
- package/dist/seo.js +3 -3
- package/package.json +4 -4
- package/dist/chunk-P5WGQRSG.js.map +0 -1
- /package/dist/{chunk-ANZBCOEH.js.map → chunk-AYWEGNEX.js.map} +0 -0
- /package/dist/{chunk-54KUQF3S.js.map → chunk-G5OVHS2V.js.map} +0 -0
- /package/dist/{chunk-M2FWG5OJ.js.map → chunk-ITJ6DX2L.js.map} +0 -0
- /package/dist/{chunk-C6HXDY46.js.map → chunk-N3LILW6D.js.map} +0 -0
- /package/dist/{chunk-ZA3IRJUQ.js.map → chunk-O3YQ5EMA.js.map} +0 -0
- /package/dist/{chunk-YOFCLTBR.js.map → chunk-ZGPZPMZD.js.map} +0 -0
- /package/dist/{config-O7QM2OQS.js.map → config-XTLZZTOF.js.map} +0 -0
- /package/dist/{host-NI3LR774.js.map → host-DIQNMXIB.js.map} +0 -0
- /package/dist/{scheduled-BWJG35Z2.js.map → scheduled-4T3QXV7A.js.map} +0 -0
|
@@ -145,7 +145,7 @@ function registerBuiltinHandlers() {
|
|
|
145
145
|
registerJobHandler("notifications:sendDigest", handleNotificationsSendDigest);
|
|
146
146
|
}
|
|
147
147
|
async function handleContentPublishScheduled(_) {
|
|
148
|
-
const { publishScheduledDocuments } = await import("./scheduled-
|
|
148
|
+
const { publishScheduledDocuments } = await import("./scheduled-4T3QXV7A.js");
|
|
149
149
|
const result = await publishScheduledDocuments();
|
|
150
150
|
if (result.published > 0) {
|
|
151
151
|
console.info(
|
|
@@ -193,7 +193,7 @@ async function handleMediaCleanup(data) {
|
|
|
193
193
|
async function handlePluginScheduledTask(data) {
|
|
194
194
|
if (isRecord(data) && typeof data.pluginId === "string" && typeof data.taskId === "string") {
|
|
195
195
|
try {
|
|
196
|
-
const { runPluginScheduledTask } = await import("./host-
|
|
196
|
+
const { runPluginScheduledTask } = await import("./host-DIQNMXIB.js");
|
|
197
197
|
await runPluginScheduledTask(data.pluginId, data.taskId);
|
|
198
198
|
return;
|
|
199
199
|
} catch (err) {
|
|
@@ -673,7 +673,7 @@ var PgBossAdapter = class {
|
|
|
673
673
|
this.workRegistrations.push({ queueName, register });
|
|
674
674
|
await register();
|
|
675
675
|
}
|
|
676
|
-
const { getRegisteredPluginSchedules, runPluginScheduledTask } = await import("./host-
|
|
676
|
+
const { getRegisteredPluginSchedules, runPluginScheduledTask } = await import("./host-DIQNMXIB.js");
|
|
677
677
|
for (const schedule of getRegisteredPluginSchedules()) {
|
|
678
678
|
const queueName = `${toQueueName("plugin:scheduledTask")}.${schedule.pluginId}.${schedule.taskId}`;
|
|
679
679
|
await this.boss.createQueue(queueName);
|
|
@@ -775,7 +775,7 @@ var PgBossAdapter = class {
|
|
|
775
775
|
});
|
|
776
776
|
await this.boss.schedule(digestQueue, "0 8 * * *", { cadence: "daily" }, { key: "daily" });
|
|
777
777
|
await this.boss.schedule(digestQueue, "0 8 * * 1", { cadence: "weekly" }, { key: "weekly" });
|
|
778
|
-
const { getRegisteredPluginSchedules } = await import("./host-
|
|
778
|
+
const { getRegisteredPluginSchedules } = await import("./host-DIQNMXIB.js");
|
|
779
779
|
for (const schedule of getRegisteredPluginSchedules()) {
|
|
780
780
|
const pgBossName = `${toQueueName("plugin:scheduledTask")}.${schedule.pluginId}.${schedule.taskId}`;
|
|
781
781
|
await this.boss.schedule(pgBossName, schedule.cron, {
|
|
@@ -939,7 +939,7 @@ var PgBossAdapter = class {
|
|
|
939
939
|
* `workerOwnsRegistrations` so the admin UI can warn the operator.
|
|
940
940
|
*/
|
|
941
941
|
async reconcilePluginSchedules() {
|
|
942
|
-
const { getRegisteredPluginSchedules } = await import("./host-
|
|
942
|
+
const { getRegisteredPluginSchedules } = await import("./host-DIQNMXIB.js");
|
|
943
943
|
const wantedList = getRegisteredPluginSchedules();
|
|
944
944
|
const wantedByName = /* @__PURE__ */ new Map();
|
|
945
945
|
for (const schedule of wantedList) {
|
|
@@ -1267,4 +1267,4 @@ export {
|
|
|
1267
1267
|
stopWorker,
|
|
1268
1268
|
stopProducer
|
|
1269
1269
|
};
|
|
1270
|
-
//# sourceMappingURL=chunk-
|
|
1270
|
+
//# sourceMappingURL=chunk-AYWEGNEX.js.map
|
|
@@ -35,7 +35,10 @@ function buildZodSchema(fields, hiddenByCondition = /* @__PURE__ */ new Set()) {
|
|
|
35
35
|
if (field.type === "group") {
|
|
36
36
|
const schema = buildZodSchema(field.fields, hiddenByCondition);
|
|
37
37
|
const effectiveRequired2 = field.required && !hiddenByCondition.has(field.name);
|
|
38
|
-
shape[field.name] =
|
|
38
|
+
shape[field.name] = applyFieldDefault(
|
|
39
|
+
applyOptionality(schema, effectiveRequired2),
|
|
40
|
+
field
|
|
41
|
+
);
|
|
39
42
|
continue;
|
|
40
43
|
}
|
|
41
44
|
const effectiveRequired = field.required && !hiddenByCondition.has(field.name);
|
|
@@ -177,4 +180,4 @@ export {
|
|
|
177
180
|
collectHiddenFieldNames,
|
|
178
181
|
getCollectionZodSchema
|
|
179
182
|
};
|
|
180
|
-
//# sourceMappingURL=chunk-
|
|
183
|
+
//# sourceMappingURL=chunk-EFZH6UPY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/collections/validation.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport {\n type NpCollectionConfig,\n type NpFieldCondition,\n type NpFieldConditionExpr,\n type NpFieldConfig,\n} from \"../config/types.js\";\n\n/**\n * Evaluate a field condition — handles both the legacy function\n * form (`NpFieldCondition`, server-side only) and the serializable\n * expression form (`NpFieldConditionExpr`, works in both env).\n * Unset → returns true (field shows / required holds).\n *\n * Used by `collectHiddenFieldNames` server-side and by the admin\n * editor's `passesCondition` client-side. The same evaluator runs\n * both places so server validation + client visibility never\n * disagree.\n */\nexport function evaluateFieldCondition(\n condition: NpFieldCondition | NpFieldConditionExpr | undefined,\n data: Record<string, unknown>,\n): boolean {\n if (!condition) return true;\n if (typeof condition === \"function\") {\n try {\n return condition(data, data);\n } catch {\n // Buggy condition: treat as \"field visible\" — surface a\n // required error is more recoverable than silently dropping.\n return true;\n }\n }\n return evaluateExpr(condition, data);\n}\n\nfunction evaluateExpr(\n expr: NpFieldConditionExpr,\n data: Record<string, unknown>,\n): boolean {\n if (\"all\" in expr) return expr.all.every((e) => evaluateExpr(e, data));\n if (\"any\" in expr) return expr.any.some((e) => evaluateExpr(e, data));\n const value = data[expr.when];\n if (\"equals\" in expr) return value === expr.equals;\n if (\"notEquals\" in expr) return value !== expr.notEquals;\n if (\"in\" in expr) return expr.in.includes(value);\n if (\"notIn\" in expr) return !expr.notIn.includes(value);\n if (\"exists\" in expr) {\n const present =\n value !== undefined &&\n value !== null &&\n value !== \"\" &&\n !(Array.isArray(value) && value.length === 0);\n return expr.exists ? present : !present;\n }\n // Exhaustiveness — unknown shape fails open (field visible)\n // so a malformed config doesn't silently hide an entire group.\n return true;\n}\n\nexport function buildZodSchema(\n fields: NpFieldConfig[],\n /**\n * Field names whose `admin.condition` returned false against\n * the current document data. `required` is dropped for these\n * — a hidden field can't be filled in by the operator, so\n * enforcing required on save would block writes the operator\n * can't fix. Pass an empty set (the default) for static\n * contexts that don't have current data to evaluate\n * conditions against; the schema then enforces every `required`\n * verbatim, matching pre-#759 behavior.\n */\n hiddenByCondition: ReadonlySet<string> = new Set(),\n): z.ZodObject<Record<string, z.ZodTypeAny>> {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const field of fields) {\n if (field.type === \"row\" || field.type === \"collapsible\") {\n Object.assign(shape, buildZodSchema(field.fields, hiddenByCondition).shape);\n continue;\n }\n\n if (field.type === \"group\") {\n const schema = buildZodSchema(field.fields, hiddenByCondition);\n const effectiveRequired = field.required && !hiddenByCondition.has(field.name);\n shape[field.name] = applyFieldDefault(\n applyOptionality(schema, effectiveRequired),\n field,\n );\n continue;\n }\n\n const effectiveRequired = field.required && !hiddenByCondition.has(field.name);\n shape[field.name] = applyFieldDefault(\n applyOptionality(buildFieldSchema(field), effectiveRequired),\n field,\n );\n }\n\n return z.object(shape);\n}\n\n/**\n * Chain `.default(field.defaultValue)` onto a Zod schema when the field\n * declares one. Without this, a field like `posts.kind` (required + select\n * with a single option + `defaultValue: \"article\"`) rejects API callers who\n * omit the field — even though the framework expected the default to fill\n * in. Drizzle column defaults run at INSERT time and don't help the Zod\n * parse step that runs first; this is the validation-layer pair.\n *\n * Applies to every leaf field type that carries a `defaultValue` AND to\n * `group` fields (a group default is an object literal merged in when the\n * caller omits the whole group). `row` / `collapsible` are pure\n * admin-layout containers with no value of their own — their nested\n * fields each carry their own default — so the function returns the\n * schema unchanged for those two.\n *\n * Only applies when `defaultValue !== undefined`. `null` is a legit\n * default for nullable text/json fields and gets forwarded as-is.\n */\nfunction applyFieldDefault(schema: z.ZodTypeAny, field: NpFieldConfig): z.ZodTypeAny {\n if (field.type === \"row\" || field.type === \"collapsible\") return schema;\n if (!(\"defaultValue\" in field)) return schema;\n if (field.defaultValue === undefined) return schema;\n return schema.default(field.defaultValue as never);\n}\n\n/**\n * Walk fields recursively, evaluating `admin.condition` against\n * `data` and collecting the names of fields the condition would\n * hide. Used by the pipeline + admin client to drop required\n * checks for fields the operator can't see / set.\n *\n * When a `group` field's own condition hides the group, every\n * nested name is added too — operators can't see the inner\n * fields, so requiring them would block save with an invisible\n * error. Nested fields with their own conditions are evaluated\n * normally when the group is visible.\n */\nexport function collectHiddenFieldNames(\n fields: NpFieldConfig[],\n data: Record<string, unknown>,\n): Set<string> {\n const out = new Set<string>();\n const addAllNames = (fs: NpFieldConfig[]): void => {\n for (const field of fs) {\n if (field.type === \"row\" || field.type === \"collapsible\") {\n addAllNames(field.fields);\n continue;\n }\n if (field.type === \"group\") {\n out.add(field.name);\n addAllNames(field.fields);\n continue;\n }\n out.add(field.name);\n }\n };\n const walk = (fs: NpFieldConfig[]): void => {\n for (const field of fs) {\n if (field.type === \"row\" || field.type === \"collapsible\") {\n walk(field.fields);\n continue;\n }\n if (field.type === \"group\") {\n const condition = field.admin?.condition;\n if (condition && !evaluateFieldCondition(condition, data)) {\n out.add(field.name);\n addAllNames(field.fields);\n continue;\n }\n walk(field.fields);\n continue;\n }\n const condition = field.admin?.condition;\n if (!condition) continue;\n if (!evaluateFieldCondition(condition, data)) {\n out.add(field.name);\n }\n }\n };\n walk(fields);\n return out;\n}\n\nexport function getCollectionZodSchema(\n config: NpCollectionConfig,\n /**\n * Current document data. When provided, `admin.condition` is\n * evaluated against it and `required` is dropped for fields\n * the condition hides — mirrors the admin client's\n * condition-aware resolver so a hidden field can't bypass\n * the editor and still fail server validation.\n *\n * Pass `undefined` (or omit) for code paths that need the\n * unconditional schema — pre-#759 behavior.\n */\n forData?: Record<string, unknown>,\n): z.ZodSchema {\n const hidden = forData ? collectHiddenFieldNames(config.fields, forData) : new Set<string>();\n const base = buildZodSchema(config.fields, hidden).extend({\n // Phase 21.17 — per-doc visibility flag. Optional on writes;\n // the pipeline lets the column default to \"public\" when the\n // caller doesn't specify. Allowed values are the same\n // codegen enum from `getBaseColumns`.\n visibility: z.enum([\"public\", \"private\"]).optional(),\n });\n // Phase 12.1 — i18n collections accept `locale` and an\n // optional `translationGroupId` on writes. zod's default\n // strip behavior would otherwise drop them before the\n // pipeline could read them. Validation of `locale` against\n // the configured locales list happens later in the pipeline\n // (we don't have the parent NpConfig here).\n if (config.i18n) {\n return base.extend({\n locale: z.string().min(1).optional(),\n translationGroupId: z.string().uuid().optional(),\n });\n }\n return base;\n}\n\nfunction buildFieldSchema(field: Exclude<NpFieldConfig, { type: \"row\" | \"collapsible\" | \"group\" }>): z.ZodTypeAny {\n switch (field.type) {\n case \"text\": {\n let schema = z.string();\n if (field.minLength !== undefined) schema = schema.min(field.minLength);\n if (field.maxLength !== undefined) schema = schema.max(field.maxLength);\n return schema;\n }\n case \"textarea\": {\n let schema = z.string();\n if (field.minLength !== undefined) schema = schema.min(field.minLength);\n if (field.maxLength !== undefined) schema = schema.max(field.maxLength);\n return schema;\n }\n case \"email\":\n return z.string().email();\n case \"number\": {\n let schema = z.number();\n if (field.integerOnly) schema = schema.int();\n if (field.min !== undefined) schema = schema.min(field.min);\n if (field.max !== undefined) schema = schema.max(field.max);\n return schema;\n }\n case \"checkbox\":\n return z.boolean();\n case \"select\":\n return createEnumSchema(field.options.map((option) => option.value));\n case \"radio\":\n return createEnumSchema(field.options.map((option) => option.value));\n case \"relationship\":\n return field.hasMany ? z.array(z.string().uuid()) : z.string().uuid();\n case \"upload\":\n return z.string().uuid();\n case \"date\":\n return z.coerce.date();\n case \"richText\":\n case \"blocks\":\n case \"json\":\n return z.unknown();\n case \"array\": {\n let schema = z.array(buildZodSchema(field.fields));\n if (field.minRows !== undefined) schema = schema.min(field.minRows);\n if (field.maxRows !== undefined) schema = schema.max(field.maxRows);\n return schema;\n }\n default:\n return z.unknown();\n }\n}\n\nfunction applyOptionality(schema: z.ZodTypeAny, required?: boolean): z.ZodTypeAny {\n return required ? schema : schema.optional().nullable();\n}\n\nfunction createEnumSchema(values: string[]): z.ZodType<string> {\n const [first, ...rest] = values;\n if (!first) {\n return z.string();\n }\n\n return z.enum([first, ...rest]);\n}\n"],"mappings":"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","names":["effectiveRequired","condition"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runHook
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-O3YQ5EMA.js";
|
|
4
4
|
import {
|
|
5
5
|
getAllCollectionSlugs,
|
|
6
6
|
getCollectionConfig,
|
|
@@ -80,4 +80,4 @@ async function publishScheduledDocuments(atTime = /* @__PURE__ */ new Date()) {
|
|
|
80
80
|
export {
|
|
81
81
|
publishScheduledDocuments
|
|
82
82
|
};
|
|
83
|
-
//# sourceMappingURL=chunk-
|
|
83
|
+
//# sourceMappingURL=chunk-G5OVHS2V.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getPluginRegistration
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-O3YQ5EMA.js";
|
|
4
4
|
import {
|
|
5
5
|
getCurrentSiteId
|
|
6
6
|
} from "./chunk-SBCVAC2Z.js";
|
|
@@ -319,4 +319,4 @@ export {
|
|
|
319
319
|
setPluginConfig,
|
|
320
320
|
pluginConfigCacheTag
|
|
321
321
|
};
|
|
322
|
-
//# sourceMappingURL=chunk-
|
|
322
|
+
//# sourceMappingURL=chunk-ITJ6DX2L.js.map
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
findDocuments,
|
|
30
30
|
getDocumentById,
|
|
31
31
|
saveDocument
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-O3YQ5EMA.js";
|
|
33
33
|
import {
|
|
34
34
|
deleteMedia
|
|
35
35
|
} from "./chunk-2VZZ7M26.js";
|
|
@@ -1956,4 +1956,4 @@ export {
|
|
|
1956
1956
|
revokeMemberRole,
|
|
1957
1957
|
purgeMemberContent
|
|
1958
1958
|
};
|
|
1959
|
-
//# sourceMappingURL=chunk-
|
|
1959
|
+
//# sourceMappingURL=chunk-N3LILW6D.js.map
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-2VZZ7M26.js";
|
|
8
8
|
import {
|
|
9
9
|
getCollectionZodSchema
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-EFZH6UPY.js";
|
|
11
11
|
import {
|
|
12
12
|
getI18nConfig
|
|
13
13
|
} from "./chunk-4ZLMEKFX.js";
|
|
@@ -1836,7 +1836,7 @@ function createPluginRuntimeContext(options) {
|
|
|
1836
1836
|
return row.value;
|
|
1837
1837
|
},
|
|
1838
1838
|
async getPlugin() {
|
|
1839
|
-
const { getPluginConfig } = await import("./config-
|
|
1839
|
+
const { getPluginConfig } = await import("./config-XTLZZTOF.js");
|
|
1840
1840
|
const value = await getPluginConfig(pluginId);
|
|
1841
1841
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
1842
1842
|
return value;
|
|
@@ -1844,8 +1844,8 @@ function createPluginRuntimeContext(options) {
|
|
|
1844
1844
|
return {};
|
|
1845
1845
|
},
|
|
1846
1846
|
async setPlugin(data) {
|
|
1847
|
-
const { setPluginConfig } = await import("./config-
|
|
1848
|
-
const { getPluginRegistration: getPluginRegistration2 } = await import("./host-
|
|
1847
|
+
const { setPluginConfig } = await import("./config-XTLZZTOF.js");
|
|
1848
|
+
const { getPluginRegistration: getPluginRegistration2 } = await import("./host-DIQNMXIB.js");
|
|
1849
1849
|
const reg = getPluginRegistration2(pluginId);
|
|
1850
1850
|
if (reg?.configSchema) {
|
|
1851
1851
|
await setPluginConfig(pluginId, data, null);
|
|
@@ -2076,7 +2076,7 @@ function invalidatePluginEnabled(pluginId) {
|
|
|
2076
2076
|
var fetchOverride = null;
|
|
2077
2077
|
|
|
2078
2078
|
// src/plugins/compat.ts
|
|
2079
|
-
var FRAMEWORK_VERSION_FROM_PACKAGE = true ? "0.3.
|
|
2079
|
+
var FRAMEWORK_VERSION_FROM_PACKAGE = true ? "0.3.5" : "0.0.0-dev";
|
|
2080
2080
|
var frameworkVersion = FRAMEWORK_VERSION_FROM_PACKAGE;
|
|
2081
2081
|
function getFrameworkVersion() {
|
|
2082
2082
|
return frameworkVersion;
|
|
@@ -2226,7 +2226,7 @@ function insertSortedByPriority(list, entry) {
|
|
|
2226
2226
|
list.sort((a, b) => a.priority - b.priority);
|
|
2227
2227
|
}
|
|
2228
2228
|
async function loadPluginConfig(pluginId) {
|
|
2229
|
-
const { getPluginConfig } = await import("./config-
|
|
2229
|
+
const { getPluginConfig } = await import("./config-XTLZZTOF.js");
|
|
2230
2230
|
const value = await getPluginConfig(pluginId);
|
|
2231
2231
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
2232
2232
|
return value;
|
|
@@ -2737,4 +2737,4 @@ export {
|
|
|
2737
2737
|
findDocuments,
|
|
2738
2738
|
getDocumentById
|
|
2739
2739
|
};
|
|
2740
|
-
//# sourceMappingURL=chunk-
|
|
2740
|
+
//# sourceMappingURL=chunk-O3YQ5EMA.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
findDocuments
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-O3YQ5EMA.js";
|
|
4
4
|
import {
|
|
5
5
|
getI18nConfig
|
|
6
6
|
} from "./chunk-4ZLMEKFX.js";
|
|
@@ -597,4 +597,4 @@ export {
|
|
|
597
597
|
buildDiscussionForumPostingJsonLd,
|
|
598
598
|
buildPersonJsonLd
|
|
599
599
|
};
|
|
600
|
-
//# sourceMappingURL=chunk-
|
|
600
|
+
//# sourceMappingURL=chunk-ZGPZPMZD.js.map
|
package/dist/community.js
CHANGED
|
@@ -33,8 +33,8 @@ import {
|
|
|
33
33
|
unfollow,
|
|
34
34
|
unresolvedReportCount,
|
|
35
35
|
updateComment
|
|
36
|
-
} from "./chunk-
|
|
37
|
-
import "./chunk-
|
|
36
|
+
} from "./chunk-N3LILW6D.js";
|
|
37
|
+
import "./chunk-G5OVHS2V.js";
|
|
38
38
|
import {
|
|
39
39
|
buildDigestEmail,
|
|
40
40
|
runDigestSweep
|
|
@@ -94,7 +94,7 @@ import {
|
|
|
94
94
|
setProfanityAdapter
|
|
95
95
|
} from "./chunk-KU5M27ZC.js";
|
|
96
96
|
import "./chunk-2N53KKIL.js";
|
|
97
|
-
import "./chunk-
|
|
97
|
+
import "./chunk-O3YQ5EMA.js";
|
|
98
98
|
import "./chunk-2VZZ7M26.js";
|
|
99
99
|
import "./chunk-EQ2Z3KMD.js";
|
|
100
100
|
import {
|
|
@@ -107,7 +107,7 @@ import {
|
|
|
107
107
|
updateCommunitySettings,
|
|
108
108
|
validateCommunitySettingsPatch
|
|
109
109
|
} from "./chunk-RKM4GDWM.js";
|
|
110
|
-
import "./chunk-
|
|
110
|
+
import "./chunk-EFZH6UPY.js";
|
|
111
111
|
import "./chunk-4ZLMEKFX.js";
|
|
112
112
|
import "./chunk-U4QCCLAW.js";
|
|
113
113
|
import "./chunk-SBCVAC2Z.js";
|
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
isVersionedPluginConfig,
|
|
6
6
|
pluginConfigCacheTag,
|
|
7
7
|
setPluginConfig
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-ITJ6DX2L.js";
|
|
9
|
+
import "./chunk-O3YQ5EMA.js";
|
|
10
10
|
import "./chunk-2VZZ7M26.js";
|
|
11
11
|
import "./chunk-LMPYQLMH.js";
|
|
12
12
|
import "./chunk-2KNG5KMM.js";
|
|
13
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-EFZH6UPY.js";
|
|
14
14
|
import "./chunk-4ZLMEKFX.js";
|
|
15
15
|
import "./chunk-U4QCCLAW.js";
|
|
16
16
|
import "./chunk-SBCVAC2Z.js";
|
|
@@ -30,4 +30,4 @@ export {
|
|
|
30
30
|
pluginConfigCacheTag,
|
|
31
31
|
setPluginConfig
|
|
32
32
|
};
|
|
33
|
-
//# sourceMappingURL=config-
|
|
33
|
+
//# sourceMappingURL=config-XTLZZTOF.js.map
|
package/dist/fields.js
CHANGED
|
@@ -16,9 +16,9 @@ import {
|
|
|
16
16
|
runHookAndCollect,
|
|
17
17
|
runPluginScheduledTask,
|
|
18
18
|
schedulePluginTask
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-O3YQ5EMA.js";
|
|
20
20
|
import "./chunk-2VZZ7M26.js";
|
|
21
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-EFZH6UPY.js";
|
|
22
22
|
import "./chunk-4ZLMEKFX.js";
|
|
23
23
|
import "./chunk-U4QCCLAW.js";
|
|
24
24
|
import "./chunk-SBCVAC2Z.js";
|
|
@@ -49,4 +49,4 @@ export {
|
|
|
49
49
|
runPluginScheduledTask,
|
|
50
50
|
schedulePluginTask
|
|
51
51
|
};
|
|
52
|
-
//# sourceMappingURL=host-
|
|
52
|
+
//# sourceMappingURL=host-DIQNMXIB.js.map
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
introspectThemeSettingsSchema,
|
|
5
5
|
pluginConfigCacheTag,
|
|
6
6
|
setPluginConfig
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-ITJ6DX2L.js";
|
|
8
8
|
import {
|
|
9
9
|
getPluginTemplatesForCollection,
|
|
10
10
|
registerPluginTemplates,
|
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
renderSitemapIndexXml,
|
|
42
42
|
renderSitemapXml,
|
|
43
43
|
validateSeoSettingsPatch
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-ZGPZPMZD.js";
|
|
45
45
|
import {
|
|
46
46
|
ARGON2_OPTIONS,
|
|
47
47
|
authenticated,
|
|
@@ -130,10 +130,10 @@ import {
|
|
|
130
130
|
unfollow,
|
|
131
131
|
unresolvedReportCount,
|
|
132
132
|
updateComment
|
|
133
|
-
} from "./chunk-
|
|
133
|
+
} from "./chunk-N3LILW6D.js";
|
|
134
134
|
import {
|
|
135
135
|
publishScheduledDocuments
|
|
136
|
-
} from "./chunk-
|
|
136
|
+
} from "./chunk-G5OVHS2V.js";
|
|
137
137
|
import {
|
|
138
138
|
buildDigestEmail,
|
|
139
139
|
runDigestSweep
|
|
@@ -229,7 +229,7 @@ import {
|
|
|
229
229
|
schedulePluginTask,
|
|
230
230
|
updateMemberDocument,
|
|
231
231
|
withDeferredPostCommit
|
|
232
|
-
} from "./chunk-
|
|
232
|
+
} from "./chunk-O3YQ5EMA.js";
|
|
233
233
|
import {
|
|
234
234
|
DEFAULT_IMAGE_SIZES,
|
|
235
235
|
cleanupDeletedMedia,
|
|
@@ -276,7 +276,7 @@ import {
|
|
|
276
276
|
collectHiddenFieldNames,
|
|
277
277
|
evaluateFieldCondition,
|
|
278
278
|
getCollectionZodSchema
|
|
279
|
-
} from "./chunk-
|
|
279
|
+
} from "./chunk-EFZH6UPY.js";
|
|
280
280
|
import {
|
|
281
281
|
formatDate,
|
|
282
282
|
formatNumber,
|
|
@@ -366,7 +366,7 @@ import {
|
|
|
366
366
|
startWorker,
|
|
367
367
|
stopProducer,
|
|
368
368
|
stopWorker
|
|
369
|
-
} from "./chunk-
|
|
369
|
+
} from "./chunk-AYWEGNEX.js";
|
|
370
370
|
import {
|
|
371
371
|
DEFAULT_JOB_LOG_RETENTION_MS,
|
|
372
372
|
countJobLogs,
|
package/dist/jobs.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
publishScheduledDocuments
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-G5OVHS2V.js";
|
|
4
|
+
import "./chunk-O3YQ5EMA.js";
|
|
5
5
|
import "./chunk-2VZZ7M26.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-EFZH6UPY.js";
|
|
7
7
|
import "./chunk-4ZLMEKFX.js";
|
|
8
8
|
import "./chunk-U4QCCLAW.js";
|
|
9
9
|
import "./chunk-SBCVAC2Z.js";
|
|
@@ -18,4 +18,4 @@ import "./chunk-PZ5AY32C.js";
|
|
|
18
18
|
export {
|
|
19
19
|
publishScheduledDocuments
|
|
20
20
|
};
|
|
21
|
-
//# sourceMappingURL=scheduled-
|
|
21
|
+
//# sourceMappingURL=scheduled-4T3QXV7A.js.map
|
package/dist/seo.js
CHANGED
|
@@ -12,10 +12,10 @@ import {
|
|
|
12
12
|
renderSitemapIndexXml,
|
|
13
13
|
renderSitemapXml,
|
|
14
14
|
validateSeoSettingsPatch
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import "./chunk-
|
|
15
|
+
} from "./chunk-ZGPZPMZD.js";
|
|
16
|
+
import "./chunk-O3YQ5EMA.js";
|
|
17
17
|
import "./chunk-2VZZ7M26.js";
|
|
18
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-EFZH6UPY.js";
|
|
19
19
|
import "./chunk-4ZLMEKFX.js";
|
|
20
20
|
import "./chunk-U4QCCLAW.js";
|
|
21
21
|
import "./chunk-SBCVAC2Z.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nexpress/core",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"description": "Server-side core for NexPress — collections pipeline, auth, jobs, media, plugins, observability.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Nexpress",
|
|
@@ -104,13 +104,13 @@
|
|
|
104
104
|
}
|
|
105
105
|
},
|
|
106
106
|
"dependencies": {
|
|
107
|
-
"@aws-sdk/client-s3": "^3.
|
|
107
|
+
"@aws-sdk/client-s3": "^3.1049.0",
|
|
108
108
|
"@node-rs/argon2": "^2.0.2",
|
|
109
109
|
"arctic": "^3.7.0",
|
|
110
110
|
"drizzle-orm": "^0.45.2",
|
|
111
111
|
"intl-messageformat": "^11.2.4",
|
|
112
|
-
"jose": "^6.2.
|
|
113
|
-
"pg": "^8.
|
|
112
|
+
"jose": "^6.2.3",
|
|
113
|
+
"pg": "^8.21.0",
|
|
114
114
|
"pg-boss": "^12.18.2",
|
|
115
115
|
"sharp": "^0.34.2",
|
|
116
116
|
"zod": "^4.4.3"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/collections/validation.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport {\n type NpCollectionConfig,\n type NpFieldCondition,\n type NpFieldConditionExpr,\n type NpFieldConfig,\n} from \"../config/types.js\";\n\n/**\n * Evaluate a field condition — handles both the legacy function\n * form (`NpFieldCondition`, server-side only) and the serializable\n * expression form (`NpFieldConditionExpr`, works in both env).\n * Unset → returns true (field shows / required holds).\n *\n * Used by `collectHiddenFieldNames` server-side and by the admin\n * editor's `passesCondition` client-side. The same evaluator runs\n * both places so server validation + client visibility never\n * disagree.\n */\nexport function evaluateFieldCondition(\n condition: NpFieldCondition | NpFieldConditionExpr | undefined,\n data: Record<string, unknown>,\n): boolean {\n if (!condition) return true;\n if (typeof condition === \"function\") {\n try {\n return condition(data, data);\n } catch {\n // Buggy condition: treat as \"field visible\" — surface a\n // required error is more recoverable than silently dropping.\n return true;\n }\n }\n return evaluateExpr(condition, data);\n}\n\nfunction evaluateExpr(\n expr: NpFieldConditionExpr,\n data: Record<string, unknown>,\n): boolean {\n if (\"all\" in expr) return expr.all.every((e) => evaluateExpr(e, data));\n if (\"any\" in expr) return expr.any.some((e) => evaluateExpr(e, data));\n const value = data[expr.when];\n if (\"equals\" in expr) return value === expr.equals;\n if (\"notEquals\" in expr) return value !== expr.notEquals;\n if (\"in\" in expr) return expr.in.includes(value);\n if (\"notIn\" in expr) return !expr.notIn.includes(value);\n if (\"exists\" in expr) {\n const present =\n value !== undefined &&\n value !== null &&\n value !== \"\" &&\n !(Array.isArray(value) && value.length === 0);\n return expr.exists ? present : !present;\n }\n // Exhaustiveness — unknown shape fails open (field visible)\n // so a malformed config doesn't silently hide an entire group.\n return true;\n}\n\nexport function buildZodSchema(\n fields: NpFieldConfig[],\n /**\n * Field names whose `admin.condition` returned false against\n * the current document data. `required` is dropped for these\n * — a hidden field can't be filled in by the operator, so\n * enforcing required on save would block writes the operator\n * can't fix. Pass an empty set (the default) for static\n * contexts that don't have current data to evaluate\n * conditions against; the schema then enforces every `required`\n * verbatim, matching pre-#759 behavior.\n */\n hiddenByCondition: ReadonlySet<string> = new Set(),\n): z.ZodObject<Record<string, z.ZodTypeAny>> {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const field of fields) {\n if (field.type === \"row\" || field.type === \"collapsible\") {\n Object.assign(shape, buildZodSchema(field.fields, hiddenByCondition).shape);\n continue;\n }\n\n if (field.type === \"group\") {\n const schema = buildZodSchema(field.fields, hiddenByCondition);\n const effectiveRequired = field.required && !hiddenByCondition.has(field.name);\n shape[field.name] = applyOptionality(schema, effectiveRequired);\n continue;\n }\n\n const effectiveRequired = field.required && !hiddenByCondition.has(field.name);\n shape[field.name] = applyFieldDefault(\n applyOptionality(buildFieldSchema(field), effectiveRequired),\n field,\n );\n }\n\n return z.object(shape);\n}\n\n/**\n * Chain `.default(field.defaultValue)` onto a Zod schema when the field\n * declares one. Without this, a field like `posts.kind` (required + select\n * with a single option + `defaultValue: \"article\"`) rejects API callers who\n * omit the field — even though the framework expected the default to fill\n * in. Drizzle column defaults run at INSERT time and don't help the Zod\n * parse step that runs first; this is the validation-layer pair.\n *\n * Only applies when `defaultValue !== undefined`. `null` is a legit\n * default for nullable text/json fields and gets forwarded as-is.\n */\nfunction applyFieldDefault(schema: z.ZodTypeAny, field: NpFieldConfig): z.ZodTypeAny {\n if (field.type === \"row\" || field.type === \"collapsible\") return schema;\n if (!(\"defaultValue\" in field)) return schema;\n if (field.defaultValue === undefined) return schema;\n return schema.default(field.defaultValue as never);\n}\n\n/**\n * Walk fields recursively, evaluating `admin.condition` against\n * `data` and collecting the names of fields the condition would\n * hide. Used by the pipeline + admin client to drop required\n * checks for fields the operator can't see / set.\n *\n * When a `group` field's own condition hides the group, every\n * nested name is added too — operators can't see the inner\n * fields, so requiring them would block save with an invisible\n * error. Nested fields with their own conditions are evaluated\n * normally when the group is visible.\n */\nexport function collectHiddenFieldNames(\n fields: NpFieldConfig[],\n data: Record<string, unknown>,\n): Set<string> {\n const out = new Set<string>();\n const addAllNames = (fs: NpFieldConfig[]): void => {\n for (const field of fs) {\n if (field.type === \"row\" || field.type === \"collapsible\") {\n addAllNames(field.fields);\n continue;\n }\n if (field.type === \"group\") {\n out.add(field.name);\n addAllNames(field.fields);\n continue;\n }\n out.add(field.name);\n }\n };\n const walk = (fs: NpFieldConfig[]): void => {\n for (const field of fs) {\n if (field.type === \"row\" || field.type === \"collapsible\") {\n walk(field.fields);\n continue;\n }\n if (field.type === \"group\") {\n const condition = field.admin?.condition;\n if (condition && !evaluateFieldCondition(condition, data)) {\n out.add(field.name);\n addAllNames(field.fields);\n continue;\n }\n walk(field.fields);\n continue;\n }\n const condition = field.admin?.condition;\n if (!condition) continue;\n if (!evaluateFieldCondition(condition, data)) {\n out.add(field.name);\n }\n }\n };\n walk(fields);\n return out;\n}\n\nexport function getCollectionZodSchema(\n config: NpCollectionConfig,\n /**\n * Current document data. When provided, `admin.condition` is\n * evaluated against it and `required` is dropped for fields\n * the condition hides — mirrors the admin client's\n * condition-aware resolver so a hidden field can't bypass\n * the editor and still fail server validation.\n *\n * Pass `undefined` (or omit) for code paths that need the\n * unconditional schema — pre-#759 behavior.\n */\n forData?: Record<string, unknown>,\n): z.ZodSchema {\n const hidden = forData ? collectHiddenFieldNames(config.fields, forData) : new Set<string>();\n const base = buildZodSchema(config.fields, hidden).extend({\n // Phase 21.17 — per-doc visibility flag. Optional on writes;\n // the pipeline lets the column default to \"public\" when the\n // caller doesn't specify. Allowed values are the same\n // codegen enum from `getBaseColumns`.\n visibility: z.enum([\"public\", \"private\"]).optional(),\n });\n // Phase 12.1 — i18n collections accept `locale` and an\n // optional `translationGroupId` on writes. zod's default\n // strip behavior would otherwise drop them before the\n // pipeline could read them. Validation of `locale` against\n // the configured locales list happens later in the pipeline\n // (we don't have the parent NpConfig here).\n if (config.i18n) {\n return base.extend({\n locale: z.string().min(1).optional(),\n translationGroupId: z.string().uuid().optional(),\n });\n }\n return base;\n}\n\nfunction buildFieldSchema(field: Exclude<NpFieldConfig, { type: \"row\" | \"collapsible\" | \"group\" }>): z.ZodTypeAny {\n switch (field.type) {\n case \"text\": {\n let schema = z.string();\n if (field.minLength !== undefined) schema = schema.min(field.minLength);\n if (field.maxLength !== undefined) schema = schema.max(field.maxLength);\n return schema;\n }\n case \"textarea\": {\n let schema = z.string();\n if (field.minLength !== undefined) schema = schema.min(field.minLength);\n if (field.maxLength !== undefined) schema = schema.max(field.maxLength);\n return schema;\n }\n case \"email\":\n return z.string().email();\n case \"number\": {\n let schema = z.number();\n if (field.integerOnly) schema = schema.int();\n if (field.min !== undefined) schema = schema.min(field.min);\n if (field.max !== undefined) schema = schema.max(field.max);\n return schema;\n }\n case \"checkbox\":\n return z.boolean();\n case \"select\":\n return createEnumSchema(field.options.map((option) => option.value));\n case \"radio\":\n return createEnumSchema(field.options.map((option) => option.value));\n case \"relationship\":\n return field.hasMany ? z.array(z.string().uuid()) : z.string().uuid();\n case \"upload\":\n return z.string().uuid();\n case \"date\":\n return z.coerce.date();\n case \"richText\":\n case \"blocks\":\n case \"json\":\n return z.unknown();\n case \"array\": {\n let schema = z.array(buildZodSchema(field.fields));\n if (field.minRows !== undefined) schema = schema.min(field.minRows);\n if (field.maxRows !== undefined) schema = schema.max(field.maxRows);\n return schema;\n }\n default:\n return z.unknown();\n }\n}\n\nfunction applyOptionality(schema: z.ZodTypeAny, required?: boolean): z.ZodTypeAny {\n return required ? schema : schema.optional().nullable();\n}\n\nfunction createEnumSchema(values: string[]): z.ZodType<string> {\n const [first, ...rest] = values;\n if (!first) {\n return z.string();\n }\n\n return z.enum([first, ...rest]);\n}\n"],"mappings":"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","names":["effectiveRequired","condition"]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|