@nexpress/core 0.2.2 → 0.3.1
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/auth.d.ts +26 -3
- package/dist/auth.js +5 -3
- package/dist/{can-FKIEV54H.js → can-UJ2NAOIR.js} +3 -3
- package/dist/{chunk-CHQJG4BB.js → chunk-2N53KKIL.js} +2 -2
- package/dist/{chunk-DWG3RZH2.js → chunk-2VZZ7M26.js} +2 -2
- package/dist/{chunk-5LCLS6VE.js → chunk-56ZK5PWM.js} +19 -19
- package/dist/{chunk-S37WWNBB.js → chunk-6IEYOY2L.js} +28 -121
- package/dist/chunk-6IEYOY2L.js.map +1 -0
- package/dist/{chunk-QYP6E5FP.js → chunk-6UV2P5MW.js} +63 -50
- package/dist/chunk-6UV2P5MW.js.map +1 -0
- package/dist/{chunk-26RYBFTF.js → chunk-AEKO4MXK.js} +21 -4
- package/dist/chunk-AEKO4MXK.js.map +1 -0
- package/dist/{chunk-L4F5RAQ5.js → chunk-DKOCKZVG.js} +9 -9
- package/dist/{chunk-KSUS4UNN.js → chunk-HUESWYZJ.js} +2 -2
- package/dist/{chunk-CTUHJHLH.js → chunk-HVHV3IHF.js} +2 -2
- package/dist/chunk-P5WGQRSG.js +180 -0
- package/dist/chunk-P5WGQRSG.js.map +1 -0
- package/dist/{chunk-HM46WM45.js → chunk-RDTTK27V.js} +6 -6
- package/dist/{chunk-PQBJWZ7D.js → chunk-RJ76SKWQ.js} +4 -4
- package/dist/{chunk-74CGJJDY.js → chunk-RKM4GDWM.js} +1 -1
- package/dist/{chunk-7GNVXRLG.js → chunk-UIQYA3Y7.js} +5 -5
- package/dist/{chunk-CKT4QZDC.js → chunk-WJJ5MBH5.js} +5 -5
- package/dist/community.d.ts +1 -1
- package/dist/community.js +20 -19
- package/dist/{config-65OBL4YH.js → config-44MFLLIX.js} +8 -7
- package/dist/db-schema.d.ts +2 -2
- package/dist/db.d.ts +3 -3
- package/dist/db.js +1 -1
- package/dist/fields.d.ts +54 -0
- package/dist/fields.js +14 -0
- package/dist/{host-55D6RX3U.js → host-DKOWZWKA.js} +6 -5
- package/dist/i18n.d.ts +1 -1
- package/dist/i18n.js +1 -1
- package/dist/{index-Ccw0AkXh.d.ts → index-BmR3Z8Y5.d.ts} +1 -1
- package/dist/{index-BWsQUGRZ.d.ts → index-C-jKU1St.d.ts} +2 -2
- package/dist/{index-D6Q7DOl7.d.ts → index-Ca-WUDH5.d.ts} +1 -1
- package/dist/{index-BpW3PGhP.d.ts → index-lACZ9sON.d.ts} +1 -1
- package/dist/index.d.ts +10 -12
- package/dist/index.js +189 -78
- package/dist/index.js.map +1 -1
- package/dist/jobs.d.ts +2 -2
- package/dist/jobs.js +2 -2
- package/dist/media.d.ts +2 -2
- package/dist/media.js +2 -2
- package/dist/{mentions-NCQR4B72.js → mentions-U4JACYI6.js} +3 -3
- package/dist/{mutes-FJSSU2JP.js → mutes-MNQP6ACF.js} +3 -3
- package/dist/{scheduled-UC7O2HBQ.js → scheduled-VEOGI5EW.js} +7 -6
- package/dist/seo.js +6 -5
- package/dist/{settings-JODDWMDB.js → settings-OZWM6L2K.js} +2 -2
- package/dist/settings-OZWM6L2K.js.map +1 -0
- package/dist/strings-4EWJYDOG.js +1 -1
- package/dist/{types-C-r01wmU.d.ts → types-BY1UmEiY.d.ts} +267 -2
- package/package.json +6 -1
- package/dist/chunk-26RYBFTF.js.map +0 -1
- package/dist/chunk-QYP6E5FP.js.map +0 -1
- package/dist/chunk-S37WWNBB.js.map +0 -1
- /package/dist/{can-FKIEV54H.js.map → can-UJ2NAOIR.js.map} +0 -0
- /package/dist/{chunk-CHQJG4BB.js.map → chunk-2N53KKIL.js.map} +0 -0
- /package/dist/{chunk-DWG3RZH2.js.map → chunk-2VZZ7M26.js.map} +0 -0
- /package/dist/{chunk-5LCLS6VE.js.map → chunk-56ZK5PWM.js.map} +0 -0
- /package/dist/{chunk-L4F5RAQ5.js.map → chunk-DKOCKZVG.js.map} +0 -0
- /package/dist/{chunk-KSUS4UNN.js.map → chunk-HUESWYZJ.js.map} +0 -0
- /package/dist/{chunk-CTUHJHLH.js.map → chunk-HVHV3IHF.js.map} +0 -0
- /package/dist/{chunk-HM46WM45.js.map → chunk-RDTTK27V.js.map} +0 -0
- /package/dist/{chunk-PQBJWZ7D.js.map → chunk-RJ76SKWQ.js.map} +0 -0
- /package/dist/{chunk-74CGJJDY.js.map → chunk-RKM4GDWM.js.map} +0 -0
- /package/dist/{chunk-7GNVXRLG.js.map → chunk-UIQYA3Y7.js.map} +0 -0
- /package/dist/{chunk-CKT4QZDC.js.map → chunk-WJJ5MBH5.js.map} +0 -0
- /package/dist/{config-65OBL4YH.js.map → config-44MFLLIX.js.map} +0 -0
- /package/dist/{host-55D6RX3U.js.map → fields.js.map} +0 -0
- /package/dist/{mentions-NCQR4B72.js.map → host-DKOWZWKA.js.map} +0 -0
- /package/dist/{mutes-FJSSU2JP.js.map → mentions-U4JACYI6.js.map} +0 -0
- /package/dist/{scheduled-UC7O2HBQ.js.map → mutes-MNQP6ACF.js.map} +0 -0
- /package/dist/{settings-JODDWMDB.js.map → scheduled-VEOGI5EW.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/db/connection.ts","../src/db/generator.ts","../src/db/type-generator.ts"],"sourcesContent":["import { drizzle } from \"drizzle-orm/node-postgres\";\nimport { Pool } from \"pg\";\n\nimport { readEnvPositiveInt } from \"../config/env.js\";\nimport * as schema from \"./schema/index.js\";\n\nexport interface CreateDbConnectionConfig {\n connectionString: string;\n pool?: Pool;\n /**\n * Override Pool option defaults. Useful for tests, or for sites that need\n * to tune connection limits / timeouts. The fields explicitly set below\n * (`connectionTimeoutMillis`, `statement_timeout`) win unless callers\n * override them here.\n */\n poolOptions?: ConstructorParameters<typeof Pool>[0];\n}\n\n/**\n * Defaults chosen so a wedged Postgres (network drop, container paused,\n * lock storm) surfaces a clear error in single-digit seconds rather than\n * letting a Next.js request handler hang past the platform's request\n * deadline. Both bounds can be raised on a per-site basis via `poolOptions`\n * or globally via `NP_DB_CONNECTION_TIMEOUT_MS` / `NP_DB_STATEMENT_TIMEOUT_MS`.\n *\n * - `connectionTimeoutMillis` caps `pool.connect()` waits — kicks in when\n * the daemon TCP-accepts but never completes the Postgres handshake (the\n * Docker-Desktop-stuck failure mode).\n * - `statement_timeout` is enforced server-side by Postgres and bounds any\n * single query, including the catch-all \"select * from np_users where\n * email = $1\" path that has to be fast on the auth hot path. Sites with\n * legitimately heavy admin workloads (large audit searches, bulk\n * exports) raise this rather than dropping the bound entirely.\n */\nconst DEFAULT_CONNECTION_TIMEOUT_MS = readEnvPositiveInt(\"NP_DB_CONNECTION_TIMEOUT_MS\", 5_000);\nconst DEFAULT_STATEMENT_TIMEOUT_MS = readEnvPositiveInt(\"NP_DB_STATEMENT_TIMEOUT_MS\", 10_000);\n\nexport function createDbConnection(config: CreateDbConnectionConfig) {\n const pool =\n config.pool ??\n new Pool({\n connectionString: config.connectionString,\n connectionTimeoutMillis: DEFAULT_CONNECTION_TIMEOUT_MS,\n statement_timeout: DEFAULT_STATEMENT_TIMEOUT_MS,\n ...config.poolOptions,\n });\n\n return drizzle(pool, { schema });\n}\n","import {\n type NpArrayField,\n type NpCollectionConfig,\n type NpFieldConfig,\n type NpRelationshipField,\n} from \"../config/types.js\";\n\ninterface TableRelation {\n key: string;\n kind: \"one\" | \"many\";\n targetIdentifier: string;\n fields?: string[];\n references?: string[];\n}\n\ninterface GeneratedTable {\n identifier: string;\n tableName: string;\n columns: string[];\n indexes: string[];\n relations: TableRelation[];\n}\n\ninterface ScalarFieldResult {\n columns: string[];\n relations: TableRelation[];\n}\n\ninterface TableContext {\n collectionSlug: string;\n tableIdentifier: string;\n tableName: string;\n relationKeyPrefix: string;\n fieldPath: string[];\n parentReferenceName: string;\n parentTargetIdentifier?: string;\n}\n\nexport interface GenerateDrizzleSchemaOptions {\n /**\n * Module specifier to import the core schema tables (npUsers, npMedia) from.\n * Defaults to \"@nexpress/core\". Override when the consumer's tooling\n * (e.g. drizzle-kit's CJS resolver) can't load the core package via its\n * exports map — point at a relative path to core's source in that case.\n */\n schemaImport?: string;\n}\n\nexport function generateDrizzleSchema(\n collections: NpCollectionConfig[],\n options?: GenerateDrizzleSchemaOptions,\n): string {\n const schemaImport = options?.schemaImport ?? \"@nexpress/core\";\n const collectionTables = new Map<string, string>();\n\n for (const collection of collections) {\n collectionTables.set(collection.slug, getCollectionTableIdentifier(collection.slug));\n }\n\n const tables: GeneratedTable[] = [];\n\n for (const collection of collections) {\n const tableIdentifier = getCollectionTableIdentifier(collection.slug);\n const tableName = `np_c_${collection.slug}`;\n const columns = getBaseColumns(collection);\n const indexes = [`index(\"${tableName}_status_idx\").on(table.status)`];\n const relations: TableRelation[] = [\n {\n key: \"createdByUser\",\n kind: \"one\",\n targetIdentifier: \"npUsers\",\n fields: [\"createdBy\"],\n references: [\"id\"],\n },\n {\n key: \"updatedByUser\",\n kind: \"one\",\n targetIdentifier: \"npUsers\",\n fields: [\"updatedBy\"],\n references: [\"id\"],\n },\n ];\n\n // Phase 9.7b: collections that opt into member-write track the\n // member-author on the row itself so update/delete can perform\n // the owner check without a separate audit-log lookup. Nullable\n // because staff-authored docs in the same table leave it null;\n // the FK to np_members keeps the column safe under member\n // deletes (cascade).\n const memberAuthored = Boolean(collection.community?.memberWrite?.create);\n if (memberAuthored) {\n columns.push(\n 'memberAuthorId: uuid(\"member_author_id\").references(() => npMembers.id, { onDelete: \"set null\" })',\n );\n indexes.push(\n `index(\"${tableName}_member_author_idx\").on(table.memberAuthorId)`,\n );\n relations.push({\n key: \"memberAuthor\",\n kind: \"one\",\n targetIdentifier: \"npMembers\",\n fields: [\"memberAuthorId\"],\n references: [\"id\"],\n });\n }\n\n const scalarResult = collectScalarColumns(collection.fields, [], collectionTables);\n columns.push(...scalarResult.columns);\n relations.push(...scalarResult.relations);\n\n if (hasSlugField(collection)) {\n columns.push('slug: text(\"slug\").notNull()');\n // Phase 15.2 — multi-site scoping. Every collection\n // table gets a `site_id` column so the same slug can\n // exist in multiple sites (e.g., `/about` on the main\n // site and on `acme.example.com`). i18n collections\n // additionally key on locale, so the unique becomes\n // `(site_id, locale, slug)`; non-i18n becomes\n // `(site_id, slug)`. Single-tenant installs leave\n // every row at `site_id = 'default'`, so the\n // uniqueness constraint behaves identically to the\n // pre-15.2 `slug-only` index.\n if (collection.i18n) {\n indexes.push(\n `uniqueIndex(\"${tableName}_site_locale_slug_idx\").on(table.siteId, table.locale, table.slug)`,\n );\n } else {\n indexes.push(\n `uniqueIndex(\"${tableName}_site_slug_idx\").on(table.siteId, table.slug)`,\n );\n }\n }\n\n if (collection.i18n) {\n columns.push('locale: text(\"locale\").notNull()');\n columns.push('translationGroupId: uuid(\"translation_group_id\").notNull()');\n indexes.push(\n `index(\"${tableName}_translation_group_idx\").on(table.translationGroupId)`,\n );\n indexes.push(\n `index(\"${tableName}_locale_idx\").on(table.locale)`,\n );\n }\n\n // Phase 15.2 — multi-site scoping column. Default is\n // 'default' so existing single-tenant deployments keep\n // working without operator intervention; the migration\n // backfills existing rows. NOT NULL so writes always\n // commit a site id; pipeline reads `getCurrentSiteId()`\n // (or falls back to 'default') and stamps every row.\n // FK to `np_sites.id` is intentionally omitted from\n // codegen — adding it forces every test fixture to\n // create the default site row first; the framework\n // invariant (default site always exists post-migration)\n // gives us the same safety without the schema-level FK.\n columns.push(\n 'siteId: text(\"site_id\").default(\"default\").notNull()',\n );\n indexes.push(`index(\"${tableName}_site_idx\").on(table.siteId)`);\n\n if (hasDraftVersions(collection)) {\n columns.push(\n '_status: text(\"_status\", { enum: [\"draft\", \"published\"] }).default(\"draft\").notNull()',\n );\n }\n\n columns.push('searchVector: tsvector(\"search_vector\")');\n\n tables.push({\n identifier: tableIdentifier,\n tableName,\n columns,\n indexes,\n relations,\n });\n\n createNestedTables(\n {\n collectionSlug: collection.slug,\n tableIdentifier,\n tableName,\n relationKeyPrefix: toCamelCase(collection.slug),\n fieldPath: [],\n parentReferenceName: `${toCamelCase(collection.slug)}Id`,\n },\n collection.fields,\n tables,\n collectionTables,\n );\n }\n\n const body = tables.map(renderTable).join(\"\\n\\n\");\n const usesMembers = collections.some((c) => c.community?.memberWrite?.create);\n const schemaImports = [\"npMedia\", \"npUsers\", ...(usesMembers ? [\"npMembers\"] : [])];\n\n return [\n 'import { relations } from \"drizzle-orm\";',\n 'import { boolean, customType, doublePrecision, index, integer, jsonb, pgTable, text, timestamp, uniqueIndex, uuid } from \"drizzle-orm/pg-core\";',\n `import { ${schemaImports.join(\", \")} } from \"${schemaImport}\";`,\n '',\n 'const tsvector = customType<{ data: string }>({',\n ' dataType() {',\n ' return \"tsvector\";',\n ' },',\n '});',\n '',\n body,\n ].join(\"\\n\");\n}\n\nfunction createNestedTables(\n context: TableContext,\n fields: NpFieldConfig[],\n tables: GeneratedTable[],\n collectionTables: Map<string, string>,\n): void {\n for (const field of fields) {\n if (field.type === \"group\") {\n createNestedTables(context, field.fields, tables, collectionTables);\n continue;\n }\n\n if (field.type === \"row\" || field.type === \"collapsible\") {\n createNestedTables(context, field.fields, tables, collectionTables);\n continue;\n }\n\n if (field.type === \"array\") {\n tables.push(createArrayTable(context, field, tables, collectionTables));\n continue;\n }\n\n if (field.type === \"relationship\" && field.hasMany && typeof field.relationTo === \"string\") {\n tables.push(\n createHasManyJoinTable(context, { ...field, relationTo: field.relationTo, hasMany: true }, collectionTables),\n );\n }\n }\n}\n\nfunction createArrayTable(\n context: TableContext,\n field: NpArrayField,\n tables: GeneratedTable[],\n collectionTables: Map<string, string>,\n): GeneratedTable {\n const path = [...context.fieldPath, field.name];\n const tableName = `np_c_${context.collectionSlug}__${path.join(\"__\")}`;\n const identifier = getNestedTableIdentifier(context.collectionSlug, path);\n const columns = [\n 'id: uuid(\"id\").defaultRandom().primaryKey()',\n `parentId: uuid(\"parent_id\").notNull().references(() => ${context.tableIdentifier}.id, { onDelete: \"cascade\" })`,\n 'order: integer(\"order\").default(0).notNull()',\n ];\n const relations: TableRelation[] = [\n {\n key: \"parent\",\n kind: \"one\",\n targetIdentifier: context.tableIdentifier,\n fields: [\"parentId\"],\n references: [\"id\"],\n },\n ];\n const scalarResult = collectScalarColumns(field.fields, [], collectionTables);\n columns.push(...scalarResult.columns);\n relations.push(...scalarResult.relations);\n\n const nestedContext: TableContext = {\n collectionSlug: context.collectionSlug,\n tableIdentifier: identifier,\n tableName,\n relationKeyPrefix: `${context.relationKeyPrefix}${toPascalCase(field.name)}`,\n fieldPath: path,\n parentReferenceName: \"parentId\",\n parentTargetIdentifier: context.tableIdentifier,\n };\n\n createNestedTables(nestedContext, field.fields, tables, collectionTables);\n\n return {\n identifier,\n tableName,\n columns,\n indexes: [`index(\"${tableName}_parent_idx\").on(table.parentId)`],\n relations,\n };\n}\n\nfunction createHasManyJoinTable(\n context: TableContext,\n field: NpRelationshipField & { relationTo: string; hasMany: true },\n collectionTables: Map<string, string>,\n): GeneratedTable {\n const path = [...context.fieldPath, field.name];\n const tableName = `np_c_${context.collectionSlug}__${path.join(\"__\")}`;\n const identifier = getNestedTableIdentifier(context.collectionSlug, path);\n const targetIdentifier = resolveRelationTarget(field.relationTo, collectionTables);\n const parentReferenceName = context.fieldPath.length === 0 ? `${toCamelCase(context.collectionSlug)}Id` : \"parentId\";\n\n return {\n identifier,\n tableName,\n columns: [\n 'id: uuid(\"id\").defaultRandom().primaryKey()',\n `${parentReferenceName}: uuid(\"${toSnakeCase(parentReferenceName)}\").notNull().references(() => ${context.tableIdentifier}.id, { onDelete: \"cascade\" })`,\n `targetId: uuid(\"target_id\").notNull().references(() => ${targetIdentifier}.id, { onDelete: \"cascade\" })`,\n 'order: integer(\"order\").default(0).notNull()',\n ],\n indexes: [\n `index(\"${tableName}_${toSnakeCase(parentReferenceName)}_idx\").on(table.${parentReferenceName})`,\n `uniqueIndex(\"${tableName}_parent_target_uidx\").on(table.${parentReferenceName}, table.targetId)`,\n ],\n relations: [\n {\n key: \"parent\",\n kind: \"one\",\n targetIdentifier: context.tableIdentifier,\n fields: [parentReferenceName],\n references: [\"id\"],\n },\n {\n key: \"target\",\n kind: \"one\",\n targetIdentifier,\n fields: [\"targetId\"],\n references: [\"id\"],\n },\n ],\n };\n}\n\nfunction collectScalarColumns(\n fields: NpFieldConfig[],\n prefix: string[],\n collectionTables: Map<string, string>,\n): ScalarFieldResult {\n const columns: string[] = [];\n const relations: TableRelation[] = [];\n\n for (const field of fields) {\n if (field.type === \"group\") {\n const nested = collectScalarColumns(field.fields, [...prefix, field.name], collectionTables);\n columns.push(...nested.columns);\n relations.push(...nested.relations);\n continue;\n }\n\n if (field.type === \"row\" || field.type === \"collapsible\") {\n const nested = collectScalarColumns(field.fields, prefix, collectionTables);\n columns.push(...nested.columns);\n relations.push(...nested.relations);\n continue;\n }\n\n if (field.type === \"array\") {\n continue;\n }\n\n if (field.type === \"relationship\" && field.hasMany) {\n continue;\n }\n\n const propertyName = getFlattenedFieldName(prefix, field.name);\n const columnName = toSnakeCase(propertyName);\n const column = buildScalarColumn(field, propertyName, columnName, collectionTables);\n\n if (!column) {\n continue;\n }\n\n columns.push(...column.columns);\n relations.push(...column.relations);\n }\n\n return { columns, relations };\n}\n\nfunction buildScalarColumn(\n field: Exclude<NpFieldConfig, { type: \"row\" | \"collapsible\" | \"group\" | \"array\" }> ,\n propertyName: string,\n columnName: string,\n collectionTables: Map<string, string>,\n): ScalarFieldResult | null {\n const notNull = field.required ? \".notNull()\" : \"\";\n\n // Honors `field.defaultValue` for SQL-mappable scalar types\n // (text family, number, checkbox). Drizzle's `.default(<expr>)`\n // emits a `DEFAULT` clause in the generated migration, which is\n // required for adding a NOT NULL column to a table that already\n // has rows. Non-scalar types (`relationship`, `upload`, `array`,\n // `group`, `richText`, `blocks`, `json`) ignore the value — those\n // either don't map to a single column or have no sensible\n // server-side default.\n const defaultClause = ((): string => {\n if (field.defaultValue === undefined || field.defaultValue === null) return \"\";\n if (field.type === \"text\" || field.type === \"textarea\" || field.type === \"email\" || field.type === \"select\" || field.type === \"radio\") {\n if (typeof field.defaultValue !== \"string\") return \"\";\n // Escape `\\` and `\"` so the emitted TS literal is a valid\n // double-quoted string. The generator's output is consumed\n // by tsc, which would reject an unescaped embedded quote.\n const literal = field.defaultValue.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n return `.default(\"${literal}\")`;\n }\n if (field.type === \"number\") {\n if (typeof field.defaultValue !== \"number\" || !Number.isFinite(field.defaultValue)) return \"\";\n return `.default(${field.defaultValue.toString()})`;\n }\n if (field.type === \"checkbox\") {\n if (typeof field.defaultValue !== \"boolean\") return \"\";\n return `.default(${field.defaultValue.toString()})`;\n }\n return \"\";\n })();\n\n switch (field.type) {\n case \"text\":\n case \"textarea\":\n case \"email\":\n case \"select\":\n case \"radio\":\n return { columns: [`${propertyName}: text(\"${columnName}\")${defaultClause}${notNull}`], relations: [] };\n case \"number\": {\n const builder = field.integerOnly ? \"integer\" : \"doublePrecision\";\n return { columns: [`${propertyName}: ${builder}(\"${columnName}\")${defaultClause}${notNull}`], relations: [] };\n }\n case \"richText\":\n case \"blocks\":\n case \"json\":\n return { columns: [`${propertyName}: jsonb(\"${columnName}\")${notNull}`], relations: [] };\n case \"checkbox\":\n return { columns: [`${propertyName}: boolean(\"${columnName}\")${defaultClause}${notNull}`], relations: [] };\n case \"date\":\n return {\n columns: [`${propertyName}: timestamp(\"${columnName}\", { withTimezone: true })${notNull}`],\n relations: [],\n };\n case \"upload\": {\n return {\n columns: [`${propertyName}: uuid(\"${columnName}\").references(() => npMedia.id)${notNull}`],\n relations: [\n {\n key: propertyName,\n kind: \"one\",\n targetIdentifier: \"npMedia\",\n fields: [propertyName],\n references: [\"id\"],\n },\n ],\n };\n }\n case \"relationship\": {\n if (typeof field.relationTo !== \"string\") {\n return null;\n }\n\n const targetIdentifier = resolveRelationTarget(field.relationTo, collectionTables);\n return {\n columns: [`${propertyName}: uuid(\"${columnName}\").references(() => ${targetIdentifier}.id)${notNull}`],\n relations: [\n {\n key: propertyName,\n kind: \"one\",\n targetIdentifier,\n fields: [propertyName],\n references: [\"id\"],\n },\n ],\n };\n }\n default:\n return null;\n }\n}\n\nfunction getBaseColumns(collection: NpCollectionConfig): string[] {\n const columns = ['id: uuid(\"id\").defaultRandom().primaryKey()'];\n\n columns.push(\n 'status: text(\"status\", { enum: [\"draft\", \"scheduled\", \"published\", \"archived\", \"pending\"] }).default(\"draft\").notNull()',\n );\n\n columns.push('createdAt: timestamp(\"created_at\", { withTimezone: true }).defaultNow().notNull()');\n columns.push('updatedAt: timestamp(\"updated_at\", { withTimezone: true }).defaultNow().notNull()');\n columns.push('createdBy: uuid(\"created_by\").references(() => npUsers.id)');\n columns.push('updatedBy: uuid(\"updated_by\").references(() => npUsers.id)');\n\n // Phase 21.17 — per-doc visibility flag. Orthogonal to\n // `status` (workflow state): a row can be published-public,\n // published-private, draft-public, etc. Anonymous reads in\n // `findDocuments` auto-filter to `visibility = \"public\"` so a\n // newly-imported \"private\" row never leaks to crawlers; an\n // authenticated principal (member or staff) sees both. WP\n // imports use this to round-trip `<wp:status>private</wp:status>`\n // posts as `status=published, visibility=private` rather than\n // the old draft-coercion that lost the publish state.\n const visibility =\n 'visibility: text(\"visibility\", { enum: [\"public\", \"private\"] }).default(\"public\").notNull()';\n\n if (collection.timestamps === false) {\n return [columns[0], columns[1], columns[4], columns[5], visibility];\n }\n\n columns.push(visibility);\n return columns;\n}\n\nfunction renderTable(table: GeneratedTable): string {\n const tableSource = [\n `export const ${table.identifier} = pgTable(`,\n ` \"${table.tableName}\",`,\n \" {\",\n ...table.columns.map((column) => ` ${column},`),\n \" },\",\n ` (table) => [${table.indexes.join(\", \")}],`,\n \");\",\n ].join(\"\\n\");\n\n const relationsSource = [\n `export const ${table.identifier}Relations = relations(${table.identifier}, ({ many, one }) => ({`,\n ...table.relations.map((relation) => renderRelation(relation, table.identifier)),\n \"}));\",\n ].join(\"\\n\");\n\n return `${tableSource}\\n\\n${relationsSource}`;\n}\n\nfunction renderRelation(relation: TableRelation, ownerIdentifier: string): string {\n if (relation.kind === \"many\") {\n return ` ${relation.key}: many(${relation.targetIdentifier}),`;\n }\n\n const fields = (relation.fields ?? [])\n .map((field) => `${ownerIdentifier}.${field}`)\n .join(\", \");\n const references = (relation.references ?? [])\n .map((reference) => `${relation.targetIdentifier}.${reference}`)\n .join(\", \");\n\n return ` ${relation.key}: one(${relation.targetIdentifier}, { fields: [${fields}], references: [${references}] }),`;\n}\n\nfunction hasSlugField(collection: NpCollectionConfig): boolean {\n return collection.slugField !== undefined && collection.slugField !== false;\n}\n\nfunction hasDraftVersions(collection: NpCollectionConfig): boolean {\n return Boolean(collection.versions?.drafts);\n}\n\nfunction resolveRelationTarget(\n relationTo: string,\n collectionTables: Map<string, string>,\n): string {\n if (relationTo === \"media\") {\n return \"npMedia\";\n }\n\n if (relationTo === \"users\") {\n return \"npUsers\";\n }\n\n return collectionTables.get(relationTo) ?? getCollectionTableIdentifier(relationTo);\n}\n\nfunction getCollectionTableIdentifier(slug: string): string {\n return `${toCamelCase(slug)}Table`;\n}\n\nfunction getNestedTableIdentifier(collectionSlug: string, path: string[]): string {\n return `${toCamelCase(collectionSlug)}${path.map(toPascalCase).join(\"\")}Table`;\n}\n\nfunction getFlattenedFieldName(prefix: string[], name: string): string {\n if (prefix.length === 0) {\n return toCamelCase(name);\n }\n\n return `${prefix.map(toPascalCase).join(\"\")}${toPascalCase(name)}`.replace(/^./u, (char) => char.toLowerCase());\n}\n\nfunction toCamelCase(value: string): string {\n const parts = splitName(value);\n const [first = \"\", ...rest] = parts;\n return `${first}${rest.map(capitalize).join(\"\")}`;\n}\n\nfunction toPascalCase(value: string): string {\n return splitName(value).map(capitalize).join(\"\");\n}\n\nfunction toSnakeCase(value: string): string {\n return value\n .replace(/([a-z0-9])([A-Z])/g, \"$1_$2\")\n .replace(/[^a-zA-Z0-9]+/g, \"_\")\n .toLowerCase();\n}\n\nfunction splitName(value: string): string[] {\n return value\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .split(/[^a-zA-Z0-9]+/)\n .map((part) => part.toLowerCase())\n .filter(Boolean);\n}\n\nfunction capitalize(value: string): string {\n return value.charAt(0).toUpperCase() + value.slice(1);\n}\n","import { type NpCollectionConfig, type NpFieldConfig } from \"../config/types.js\";\n\nexport function generateTypeScript(collections: NpCollectionConfig[]): string {\n const interfaces = collections.map((collection) => renderCollectionInterface(collection));\n return interfaces.join(\"\\n\\n\");\n}\n\ninterface HasManyDescriptor {\n /** Field name on the collection (the where clause key). */\n fieldName: string;\n /** Generated join-table import name (e.g., `postsCategoriesTable`). */\n joinTable: string;\n /** Parent FK column on the join table (e.g., `postsId`). */\n parentColumn: string;\n}\n\nfunction collectHasManyFields(collection: NpCollectionConfig): HasManyDescriptor[] {\n const collCamel = toCamelCase(collection.slug);\n const parentColumn = `${collCamel}Id`;\n const out: HasManyDescriptor[] = [];\n // Only top-level fields participate. Nested hasMany (inside row /\n // collapsible / group / array) is rare in practice and the join-\n // table naming convention doesn't carry through nesting cleanly.\n for (const field of collection.fields) {\n if (field.type === \"relationship\" && field.hasMany === true) {\n const joinTable = `${collCamel}${toPascalCase(field.name)}Table`;\n out.push({ fieldName: field.name, joinTable, parentColumn });\n }\n }\n return out;\n}\n\n/**\n * Renders a complete `documents.ts` module: imports from\n * `@nexpress/core`, per-collection `${Pascal}Document` interfaces,\n * and typed read-helper wrappers (`find${Pascal}` /\n * `get${Pascal}Document`) that bind the type generic so call sites\n * don't have to.\n *\n * Collections with hasMany relationship fields get a smarter\n * wrapper: when the caller's `where` clause names a hasMany\n * field, the wrapper queries the join table for matching parent\n * ids first, intersects across multiple hasMany filters, and\n * delegates to `findDocuments` with `id: idList`. That covers\n * the friction surfaced in #540's category-page dogfood — a\n * `where: { categories: id }` filter looked typed but failed at\n * runtime because `categories` isn't a column on the parent\n * table; this wrapper makes it work.\n *\n * The output is meant for `apps/<app>/src/db/generated/documents.ts`\n * and is a direct counterpart to `generateDrizzleSchema`'s\n * `collections.ts` (Drizzle schema). Both files come from the same\n * `nexpressConfig.collections` source so they stay in sync.\n */\nexport function generateDocumentsModule(collections: NpCollectionConfig[]): string {\n const hasManyByCollection = new Map(\n collections.map((c) => [c.slug, collectHasManyFields(c)]),\n );\n const anyHasMany = Array.from(hasManyByCollection.values()).some(\n (list) => list.length > 0,\n );\n\n const coreImports = [\n `import {`,\n ` findDocuments,`,\n ...(anyHasMany ? [` getDb,`] : []),\n ` getDocumentById,`,\n ` type NpAuthUser,`,\n ` type NpFindOptions,`,\n ` type NpFindResult,`,\n `} from \"@nexpress/core\";`,\n ].join(\"\\n\");\n\n // Drizzle + join-table imports only when at least one collection\n // has a hasMany relationship — keeps the file lean for sites\n // that don't use them.\n const drizzleImports = anyHasMany\n ? [\n `import { inArray } from \"drizzle-orm\";`,\n `import type { NodePgDatabase } from \"drizzle-orm/node-postgres\";`,\n ].join(\"\\n\")\n : \"\";\n const joinTables = Array.from(\n new Set(\n Array.from(hasManyByCollection.values())\n .flat()\n .map((d) => d.joinTable),\n ),\n ).sort();\n // Emit without the `.js` extension. The reference app's\n // `apps/web/tsconfig.json` uses `moduleResolution: \"Bundler\"`\n // (Next 16's standard); Bundler resolution + Turbopack don't\n // rewrite `.js` → `.ts` for relative imports the way tsc's\n // NodeNext resolution does, so the explicit extension breaks\n // `next build` even though `pnpm typecheck` passes (tsc handles\n // both shapes). Extension-less imports work under both\n // resolution strategies — Bundler resolves to the `.ts` file\n // directly, NodeNext does the same when the file extension\n // is omitted in TS source. See\n // https://github.com/vercel/next.js/issues for the long\n // history of `.js`-extension friction with Turbopack.\n const joinTableImports =\n joinTables.length > 0\n ? `import { ${joinTables.join(\", \")} } from \"./collections\";`\n : \"\";\n\n const imports = [coreImports, drizzleImports, joinTableImports]\n .filter(Boolean)\n .join(\"\\n\");\n\n const interfaces = collections.map((c) => renderCollectionInterface(c)).join(\"\\n\\n\");\n const helpers = collections\n .map((c) => renderReadHelpers(c, hasManyByCollection.get(c.slug) ?? []))\n .join(\"\\n\\n\");\n\n return [imports, \"\", interfaces, \"\", helpers, \"\"].join(\"\\n\");\n}\n\nfunction renderReadHelpers(\n collection: NpCollectionConfig,\n hasMany: HasManyDescriptor[],\n): string {\n const docType = `${toPascalCase(collection.slug)}Document`;\n const findFnName = `find${toPascalCase(collection.slug)}`;\n const getFnName = `get${toPascalCase(collection.slug)}Document`;\n const slug = JSON.stringify(collection.slug);\n\n const findFn =\n hasMany.length === 0\n ? renderSimpleFindFn(findFnName, slug, docType, collection.slug)\n : renderHasManyFindFn(findFnName, slug, docType, collection.slug, hasMany);\n\n return [\n findFn,\n \"\",\n `/** Typed by-id fetch for the \\`${collection.slug}\\` collection. */`,\n `export function ${getFnName}(`,\n ` id: string,`,\n ` user?: NpAuthUser,`,\n `): Promise<${docType} | null> {`,\n ` return getDocumentById<${docType}>(${slug}, id, user);`,\n `}`,\n ].join(\"\\n\");\n}\n\nfunction renderSimpleFindFn(\n findFnName: string,\n slug: string,\n docType: string,\n slugLabel: string,\n): string {\n return [\n `/** Typed listing query for the \\`${slugLabel}\\` collection. */`,\n `export function ${findFnName}(`,\n ` options: NpFindOptions<${docType}> = {},`,\n ` user?: NpAuthUser,`,\n `): Promise<NpFindResult<${docType}>> {`,\n ` return findDocuments<${docType}>(${slug}, options, user);`,\n `}`,\n ].join(\"\\n\");\n}\n\nfunction renderHasManyFindFn(\n findFnName: string,\n slug: string,\n docType: string,\n slugLabel: string,\n hasMany: HasManyDescriptor[],\n): string {\n // Build a literal array of `{ field, table, column }` for\n // runtime iteration. Keep it inline (instead of a loose const)\n // so the wrapper is one self-contained function — no helpers\n // bleed into consumer code completion.\n const descriptors = hasMany\n .map(\n (d) =>\n ` { field: ${JSON.stringify(d.fieldName)}, table: ${d.joinTable}, parent: ${d.joinTable}.${d.parentColumn} },`,\n )\n .join(\"\\n\");\n\n return [\n `/**`,\n ` * Typed listing query for the \\`${slugLabel}\\` collection.`,\n ` *`,\n ` * Pre-resolves hasMany relationship filters in the where`,\n ` * clause (${hasMany.map((d) => `\\`${d.fieldName}\\``).join(\", \")}) by`,\n ` * subquerying the join table for matching parent ids. Each`,\n ` * field accepts a single target id (most common) or an array`,\n ` * of target ids (OR semantics). Multiple hasMany filters`,\n ` * intersect — \\`where: { categories: catId, tags: tagId }\\``,\n ` * matches rows that have BOTH.`,\n ` */`,\n `export async function ${findFnName}(`,\n ` options: NpFindOptions<${docType}> = {},`,\n ` user?: NpAuthUser,`,\n `): Promise<NpFindResult<${docType}>> {`,\n ` const where = options.where ? { ...options.where } : {};`,\n ` const hasManyDescriptors = [`,\n descriptors,\n ` ];`,\n ``,\n ` const matched: string[][] = [];`,\n ` let touchedHasMany = false;`,\n ` for (const { field, table, parent } of hasManyDescriptors) {`,\n ` const value = (where as Record<string, unknown>)[field];`,\n ` if (value === undefined) continue;`,\n ` touchedHasMany = true;`,\n ` delete (where as Record<string, unknown>)[field];`,\n ` const targets = (Array.isArray(value) ? value : [value]).filter(`,\n ` (v): v is string => typeof v === \"string\" && v.length > 0,`,\n ` );`,\n ` if (targets.length === 0) {`,\n ` // Empty array short-circuits to no rows — match the`,\n ` // pipeline's array-where semantics.`,\n ` matched.push([]);`,\n ` continue;`,\n ` }`,\n ` // Cast getDb() to NodePgDatabase so the drizzle builder`,\n ` // chain (.select.from.where) carries proper return types.`,\n ` // The empty-schema generic narrows the return shape away`,\n ` // from any specific tables; the explicit \\`{ id: string }[]\\` `,\n ` // cast at the end matches the projection.`,\n ` const db = getDb() as unknown as NodePgDatabase<Record<string, never>>;`,\n ` const rows = (await db`,\n ` .select({ id: parent })`,\n ` .from(table)`,\n ` .where(inArray(table.targetId, targets))) as Array<{ id: string }>;`,\n ` matched.push(rows.map((r) => r.id));`,\n ` }`,\n ``,\n ` if (touchedHasMany) {`,\n ` // Intersect across all hasMany filters. Empty intersection`,\n ` // → return immediately; findDocuments would short-circuit`,\n ` // on the empty-array where clause anyway, but the early`,\n ` // exit saves a round-trip.`,\n ` let ids = matched[0] ?? [];`,\n ` for (let i = 1; i < matched.length; i++) {`,\n ` const set = new Set(matched[i]);`,\n ` ids = ids.filter((id) => set.has(id));`,\n ` }`,\n ``,\n ` // Honor any pre-existing user id constraint. Without this,`,\n ` // \\`where: { id: someId, categories: catId }\\` would silently`,\n ` // drop the user's id filter and return every post in that`,\n ` // category — a real foot-gun. Intersect instead.`,\n ` const existingId = (where as Record<string, unknown>).id;`,\n ` if (typeof existingId === \"string\") {`,\n ` ids = ids.includes(existingId) ? [existingId] : [];`,\n ` } else if (Array.isArray(existingId)) {`,\n ` const allowed = new Set(`,\n ` existingId.filter((v): v is string => typeof v === \"string\"),`,\n ` );`,\n ` ids = ids.filter((id) => allowed.has(id));`,\n ` }`,\n ``,\n ` if (ids.length === 0) {`,\n ` return {`,\n ` docs: [],`,\n ` totalDocs: 0,`,\n ` totalPages: 0,`,\n ` page: options.page ?? 1,`,\n ` limit: options.limit ?? 20,`,\n ` hasNextPage: false,`,\n ` hasPrevPage: false,`,\n ` };`,\n ` }`,\n ` (where as Record<string, unknown>).id = ids;`,\n ` }`,\n ``,\n ` return findDocuments<${docType}>(${slug}, { ...options, where }, user);`,\n `}`,\n ].join(\"\\n\");\n}\n\nfunction renderCollectionInterface(collection: NpCollectionConfig): string {\n const interfaceName = `${toPascalCase(collection.slug)}Document`;\n const fields = [\n 'id: string;',\n 'status: \"draft\" | \"published\" | \"archived\" | \"pending\";',\n 'createdAt: Date;',\n 'updatedAt: Date;',\n 'createdBy: string | null;',\n 'updatedBy: string | null;',\n ];\n\n if (collection.community?.memberWrite?.create) {\n fields.push('memberAuthorId: string | null;');\n }\n\n if (collection.slugField) {\n fields.push(\"slug: string;\");\n }\n\n if (collection.versions?.drafts) {\n fields.push('_status: \"draft\" | \"published\";');\n }\n\n fields.push(...renderFields(collection.fields));\n\n return [`export interface ${interfaceName} {`, ...fields.map((field) => ` ${field}`), \"}\"].join(\"\\n\");\n}\n\nfunction renderFields(fields: NpFieldConfig[], prefix: string[] = []): string[] {\n const lines: string[] = [];\n\n for (const field of fields) {\n if (field.type === \"row\" || field.type === \"collapsible\") {\n lines.push(...renderFields(field.fields, prefix));\n continue;\n }\n\n const fieldName = field.type === \"group\" ? getPropertyName(prefix, field.name) : \"\";\n\n if (field.type === \"group\") {\n const groupType = renderObjectType(field.fields);\n lines.push(`${fieldName}: ${applyNullability(groupType, field.required)};`);\n continue;\n }\n\n const propertyName = getPropertyName(prefix, field.name);\n const typeSource = getTypeSource(field);\n lines.push(`${propertyName}: ${applyNullability(typeSource, field.required)};`);\n }\n\n return lines;\n}\n\nfunction renderObjectType(fields: NpFieldConfig[]): string {\n const members = renderFields(fields).map((field) => ` ${field}`);\n return [`{`, ...members, `}`].join(\"\\n\");\n}\n\nfunction getTypeSource(field: Exclude<NpFieldConfig, { type: \"row\" | \"collapsible\" | \"group\" }>): string {\n switch (field.type) {\n case \"text\":\n case \"textarea\":\n case \"email\":\n case \"select\":\n case \"radio\":\n return \"string\";\n case \"number\":\n return \"number\";\n case \"checkbox\":\n return \"boolean\";\n case \"date\":\n return \"Date\";\n case \"upload\":\n return \"string\";\n case \"relationship\":\n return field.hasMany ? \"string[]\" : \"string\";\n case \"array\":\n return `Array<${renderObjectType(field.fields)}>`;\n case \"richText\":\n case \"blocks\":\n case \"json\":\n return \"unknown\";\n default:\n return \"unknown\";\n }\n}\n\nfunction applyNullability(typeSource: string, required?: boolean): string {\n return required ? typeSource : `${typeSource} | null`;\n}\n\nfunction getPropertyName(prefix: string[], name: string): string {\n if (prefix.length === 0) {\n return toCamelCase(name);\n }\n\n return `${prefix[0]}${prefix.slice(1).map(toPascalCase).join(\"\")}${toPascalCase(name)}`;\n}\n\nfunction toCamelCase(value: string): string {\n const parts = splitName(value);\n const [first = \"\", ...rest] = parts;\n return `${first}${rest.map(toPascalCase).join(\"\")}`;\n}\n\nfunction toPascalCase(value: string): string {\n return splitName(value)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\"\");\n}\n\nfunction splitName(value: string): string[] {\n return value\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .split(/[^a-zA-Z0-9]+/)\n .map((part) => part.toLowerCase())\n .filter(Boolean);\n}\n"],"mappings":"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","names":["toCamelCase","toPascalCase","splitName"]}
|
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
getEmailAdapter
|
|
7
7
|
} from "./chunk-LSHHRDVR.js";
|
|
8
|
-
import {
|
|
9
|
-
reportError
|
|
10
|
-
} from "./chunk-WV272MPW.js";
|
|
11
8
|
import {
|
|
12
9
|
setJobQueue
|
|
13
10
|
} from "./chunk-V2UNHGAP.js";
|
|
11
|
+
import {
|
|
12
|
+
reportError
|
|
13
|
+
} from "./chunk-WV272MPW.js";
|
|
14
14
|
import {
|
|
15
15
|
readEnvPositiveInt
|
|
16
16
|
} from "./chunk-OROPGO65.js";
|
|
@@ -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-VEOGI5EW.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-DKOWZWKA.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-DKOWZWKA.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-DKOWZWKA.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-DKOWZWKA.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-DKOCKZVG.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runHook
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6IEYOY2L.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-HUESWYZJ.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
findDocuments
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6IEYOY2L.js";
|
|
4
4
|
import {
|
|
5
5
|
getI18nConfig
|
|
6
6
|
} from "./chunk-4ZLMEKFX.js";
|
|
@@ -594,4 +594,4 @@ export {
|
|
|
594
594
|
buildDiscussionForumPostingJsonLd,
|
|
595
595
|
buildPersonJsonLd
|
|
596
596
|
};
|
|
597
|
-
//# sourceMappingURL=chunk-
|
|
597
|
+
//# sourceMappingURL=chunk-HVHV3IHF.js.map
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// src/collections/validation.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
function evaluateFieldCondition(condition, data) {
|
|
4
|
+
if (!condition) return true;
|
|
5
|
+
if (typeof condition === "function") {
|
|
6
|
+
try {
|
|
7
|
+
return condition(data, data);
|
|
8
|
+
} catch {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return evaluateExpr(condition, data);
|
|
13
|
+
}
|
|
14
|
+
function evaluateExpr(expr, data) {
|
|
15
|
+
if ("all" in expr) return expr.all.every((e) => evaluateExpr(e, data));
|
|
16
|
+
if ("any" in expr) return expr.any.some((e) => evaluateExpr(e, data));
|
|
17
|
+
const value = data[expr.when];
|
|
18
|
+
if ("equals" in expr) return value === expr.equals;
|
|
19
|
+
if ("notEquals" in expr) return value !== expr.notEquals;
|
|
20
|
+
if ("in" in expr) return expr.in.includes(value);
|
|
21
|
+
if ("notIn" in expr) return !expr.notIn.includes(value);
|
|
22
|
+
if ("exists" in expr) {
|
|
23
|
+
const present = value !== void 0 && value !== null && value !== "" && !(Array.isArray(value) && value.length === 0);
|
|
24
|
+
return expr.exists ? present : !present;
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
function buildZodSchema(fields, hiddenByCondition = /* @__PURE__ */ new Set()) {
|
|
29
|
+
const shape = {};
|
|
30
|
+
for (const field of fields) {
|
|
31
|
+
if (field.type === "row" || field.type === "collapsible") {
|
|
32
|
+
Object.assign(shape, buildZodSchema(field.fields, hiddenByCondition).shape);
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (field.type === "group") {
|
|
36
|
+
const schema = buildZodSchema(field.fields, hiddenByCondition);
|
|
37
|
+
const effectiveRequired2 = field.required && !hiddenByCondition.has(field.name);
|
|
38
|
+
shape[field.name] = applyOptionality(schema, effectiveRequired2);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const effectiveRequired = field.required && !hiddenByCondition.has(field.name);
|
|
42
|
+
shape[field.name] = applyFieldDefault(
|
|
43
|
+
applyOptionality(buildFieldSchema(field), effectiveRequired),
|
|
44
|
+
field
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
return z.object(shape);
|
|
48
|
+
}
|
|
49
|
+
function applyFieldDefault(schema, field) {
|
|
50
|
+
if (field.type === "row" || field.type === "collapsible") return schema;
|
|
51
|
+
if (!("defaultValue" in field)) return schema;
|
|
52
|
+
if (field.defaultValue === void 0) return schema;
|
|
53
|
+
return schema.default(field.defaultValue);
|
|
54
|
+
}
|
|
55
|
+
function collectHiddenFieldNames(fields, data) {
|
|
56
|
+
const out = /* @__PURE__ */ new Set();
|
|
57
|
+
const addAllNames = (fs) => {
|
|
58
|
+
for (const field of fs) {
|
|
59
|
+
if (field.type === "row" || field.type === "collapsible") {
|
|
60
|
+
addAllNames(field.fields);
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (field.type === "group") {
|
|
64
|
+
out.add(field.name);
|
|
65
|
+
addAllNames(field.fields);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
out.add(field.name);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
const walk = (fs) => {
|
|
72
|
+
for (const field of fs) {
|
|
73
|
+
if (field.type === "row" || field.type === "collapsible") {
|
|
74
|
+
walk(field.fields);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (field.type === "group") {
|
|
78
|
+
const condition2 = field.admin?.condition;
|
|
79
|
+
if (condition2 && !evaluateFieldCondition(condition2, data)) {
|
|
80
|
+
out.add(field.name);
|
|
81
|
+
addAllNames(field.fields);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
walk(field.fields);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const condition = field.admin?.condition;
|
|
88
|
+
if (!condition) continue;
|
|
89
|
+
if (!evaluateFieldCondition(condition, data)) {
|
|
90
|
+
out.add(field.name);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
walk(fields);
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
function getCollectionZodSchema(config, forData) {
|
|
98
|
+
const hidden = forData ? collectHiddenFieldNames(config.fields, forData) : /* @__PURE__ */ new Set();
|
|
99
|
+
const base = buildZodSchema(config.fields, hidden).extend({
|
|
100
|
+
// Phase 21.17 — per-doc visibility flag. Optional on writes;
|
|
101
|
+
// the pipeline lets the column default to "public" when the
|
|
102
|
+
// caller doesn't specify. Allowed values are the same
|
|
103
|
+
// codegen enum from `getBaseColumns`.
|
|
104
|
+
visibility: z.enum(["public", "private"]).optional()
|
|
105
|
+
});
|
|
106
|
+
if (config.i18n) {
|
|
107
|
+
return base.extend({
|
|
108
|
+
locale: z.string().min(1).optional(),
|
|
109
|
+
translationGroupId: z.string().uuid().optional()
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
return base;
|
|
113
|
+
}
|
|
114
|
+
function buildFieldSchema(field) {
|
|
115
|
+
switch (field.type) {
|
|
116
|
+
case "text": {
|
|
117
|
+
let schema = z.string();
|
|
118
|
+
if (field.minLength !== void 0) schema = schema.min(field.minLength);
|
|
119
|
+
if (field.maxLength !== void 0) schema = schema.max(field.maxLength);
|
|
120
|
+
return schema;
|
|
121
|
+
}
|
|
122
|
+
case "textarea": {
|
|
123
|
+
let schema = z.string();
|
|
124
|
+
if (field.minLength !== void 0) schema = schema.min(field.minLength);
|
|
125
|
+
if (field.maxLength !== void 0) schema = schema.max(field.maxLength);
|
|
126
|
+
return schema;
|
|
127
|
+
}
|
|
128
|
+
case "email":
|
|
129
|
+
return z.string().email();
|
|
130
|
+
case "number": {
|
|
131
|
+
let schema = z.number();
|
|
132
|
+
if (field.integerOnly) schema = schema.int();
|
|
133
|
+
if (field.min !== void 0) schema = schema.min(field.min);
|
|
134
|
+
if (field.max !== void 0) schema = schema.max(field.max);
|
|
135
|
+
return schema;
|
|
136
|
+
}
|
|
137
|
+
case "checkbox":
|
|
138
|
+
return z.boolean();
|
|
139
|
+
case "select":
|
|
140
|
+
return createEnumSchema(field.options.map((option) => option.value));
|
|
141
|
+
case "radio":
|
|
142
|
+
return createEnumSchema(field.options.map((option) => option.value));
|
|
143
|
+
case "relationship":
|
|
144
|
+
return field.hasMany ? z.array(z.string().uuid()) : z.string().uuid();
|
|
145
|
+
case "upload":
|
|
146
|
+
return z.string().uuid();
|
|
147
|
+
case "date":
|
|
148
|
+
return z.coerce.date();
|
|
149
|
+
case "richText":
|
|
150
|
+
case "blocks":
|
|
151
|
+
case "json":
|
|
152
|
+
return z.unknown();
|
|
153
|
+
case "array": {
|
|
154
|
+
let schema = z.array(buildZodSchema(field.fields));
|
|
155
|
+
if (field.minRows !== void 0) schema = schema.min(field.minRows);
|
|
156
|
+
if (field.maxRows !== void 0) schema = schema.max(field.maxRows);
|
|
157
|
+
return schema;
|
|
158
|
+
}
|
|
159
|
+
default:
|
|
160
|
+
return z.unknown();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function applyOptionality(schema, required) {
|
|
164
|
+
return required ? schema : schema.optional().nullable();
|
|
165
|
+
}
|
|
166
|
+
function createEnumSchema(values) {
|
|
167
|
+
const [first, ...rest] = values;
|
|
168
|
+
if (!first) {
|
|
169
|
+
return z.string();
|
|
170
|
+
}
|
|
171
|
+
return z.enum([first, ...rest]);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export {
|
|
175
|
+
evaluateFieldCondition,
|
|
176
|
+
buildZodSchema,
|
|
177
|
+
collectHiddenFieldNames,
|
|
178
|
+
getCollectionZodSchema
|
|
179
|
+
};
|
|
180
|
+
//# sourceMappingURL=chunk-P5WGQRSG.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] = 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"]}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
NP_DEFAULT_SITE_ID
|
|
3
3
|
} from "./chunk-U4QCCLAW.js";
|
|
4
|
-
import {
|
|
5
|
-
NpForbiddenError,
|
|
6
|
-
NpValidationError
|
|
7
|
-
} from "./chunk-ZCINJSS4.js";
|
|
8
4
|
import {
|
|
9
5
|
getCurrentSiteId,
|
|
10
6
|
requireSiteId
|
|
11
7
|
} from "./chunk-SBCVAC2Z.js";
|
|
8
|
+
import {
|
|
9
|
+
NpForbiddenError,
|
|
10
|
+
NpValidationError
|
|
11
|
+
} from "./chunk-ZCINJSS4.js";
|
|
12
12
|
import {
|
|
13
13
|
getDb
|
|
14
14
|
} from "./chunk-XANPEOJC.js";
|
|
@@ -24,7 +24,7 @@ import { inArray as inArray2 } from "drizzle-orm";
|
|
|
24
24
|
import { and, count, desc, eq, isNull, inArray } from "drizzle-orm";
|
|
25
25
|
async function createNotification(input) {
|
|
26
26
|
if (input.actorMemberId && input.actorMemberId !== input.memberId) {
|
|
27
|
-
const { isMuted } = await import("./mutes-
|
|
27
|
+
const { isMuted } = await import("./mutes-MNQP6ACF.js");
|
|
28
28
|
const muted = await isMuted({
|
|
29
29
|
memberId: input.memberId,
|
|
30
30
|
targetId: input.actorMemberId
|
|
@@ -219,4 +219,4 @@ export {
|
|
|
219
219
|
resolveMentionedMembers,
|
|
220
220
|
fanOutMentionNotifications
|
|
221
221
|
};
|
|
222
|
-
//# sourceMappingURL=chunk-
|
|
222
|
+
//# sourceMappingURL=chunk-RDTTK27V.js.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
NP_DEFAULT_SITE_ID
|
|
3
3
|
} from "./chunk-U4QCCLAW.js";
|
|
4
|
-
import {
|
|
5
|
-
NpForbiddenError
|
|
6
|
-
} from "./chunk-ZCINJSS4.js";
|
|
7
4
|
import {
|
|
8
5
|
getCurrentSiteId
|
|
9
6
|
} from "./chunk-SBCVAC2Z.js";
|
|
7
|
+
import {
|
|
8
|
+
NpForbiddenError
|
|
9
|
+
} from "./chunk-ZCINJSS4.js";
|
|
10
10
|
import {
|
|
11
11
|
getDb
|
|
12
12
|
} from "./chunk-XANPEOJC.js";
|
|
@@ -176,4 +176,4 @@ export {
|
|
|
176
176
|
withMemberWrite,
|
|
177
177
|
memberCan
|
|
178
178
|
};
|
|
179
|
-
//# sourceMappingURL=chunk-
|
|
179
|
+
//# sourceMappingURL=chunk-RJ76SKWQ.js.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getPluginRegistration
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import {
|
|
5
|
-
NpValidationError
|
|
6
|
-
} from "./chunk-ZCINJSS4.js";
|
|
3
|
+
} from "./chunk-6IEYOY2L.js";
|
|
7
4
|
import {
|
|
8
5
|
getCurrentSiteId
|
|
9
6
|
} from "./chunk-SBCVAC2Z.js";
|
|
7
|
+
import {
|
|
8
|
+
NpValidationError
|
|
9
|
+
} from "./chunk-ZCINJSS4.js";
|
|
10
10
|
import {
|
|
11
11
|
getDb
|
|
12
12
|
} from "./chunk-XANPEOJC.js";
|
|
@@ -319,4 +319,4 @@ export {
|
|
|
319
319
|
setPluginConfig,
|
|
320
320
|
pluginConfigCacheTag
|
|
321
321
|
};
|
|
322
|
-
//# sourceMappingURL=chunk-
|
|
322
|
+
//# sourceMappingURL=chunk-UIQYA3Y7.js.map
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
NP_DEFAULT_SITE_ID
|
|
3
3
|
} from "./chunk-U4QCCLAW.js";
|
|
4
|
-
import {
|
|
5
|
-
NpNotFoundError,
|
|
6
|
-
NpValidationError
|
|
7
|
-
} from "./chunk-ZCINJSS4.js";
|
|
8
4
|
import {
|
|
9
5
|
getCurrentSiteId,
|
|
10
6
|
requireSiteId
|
|
11
7
|
} from "./chunk-SBCVAC2Z.js";
|
|
8
|
+
import {
|
|
9
|
+
NpNotFoundError,
|
|
10
|
+
NpValidationError
|
|
11
|
+
} from "./chunk-ZCINJSS4.js";
|
|
12
12
|
import {
|
|
13
13
|
getDb
|
|
14
14
|
} from "./chunk-XANPEOJC.js";
|
|
@@ -98,4 +98,4 @@ export {
|
|
|
98
98
|
getMutedTargetIds,
|
|
99
99
|
listMutes
|
|
100
100
|
};
|
|
101
|
-
//# sourceMappingURL=chunk-
|
|
101
|
+
//# sourceMappingURL=chunk-WJJ5MBH5.js.map
|
package/dist/community.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NodePgDatabase } from 'drizzle-orm/node-postgres';
|
|
2
|
-
import {
|
|
2
|
+
import { H as NpPrincipal, e as NpAuthUser } from './types-BY1UmEiY.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Community role registry. Maps a role name + scope type to the
|
package/dist/community.js
CHANGED
|
@@ -33,18 +33,28 @@ import {
|
|
|
33
33
|
unfollow,
|
|
34
34
|
unresolvedReportCount,
|
|
35
35
|
updateComment
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-56ZK5PWM.js";
|
|
37
|
+
import "./chunk-HUESWYZJ.js";
|
|
37
38
|
import {
|
|
38
39
|
buildDigestEmail,
|
|
39
40
|
runDigestSweep
|
|
40
41
|
} from "./chunk-LN6NTH6E.js";
|
|
42
|
+
import {
|
|
43
|
+
assertNotBanned,
|
|
44
|
+
getCommunityRole,
|
|
45
|
+
listCommunityRoles,
|
|
46
|
+
memberCan,
|
|
47
|
+
registerCommunityRole,
|
|
48
|
+
resetCommunityRoles,
|
|
49
|
+
withMemberWrite
|
|
50
|
+
} from "./chunk-RJ76SKWQ.js";
|
|
41
51
|
import {
|
|
42
52
|
getMutedTargetIds,
|
|
43
53
|
isMuted,
|
|
44
54
|
listMutes,
|
|
45
55
|
muteMember,
|
|
46
56
|
unmuteMember
|
|
47
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-WJJ5MBH5.js";
|
|
48
58
|
import {
|
|
49
59
|
getMemberNotificationPrefs,
|
|
50
60
|
isNotificationKindEnabled,
|
|
@@ -66,7 +76,7 @@ import {
|
|
|
66
76
|
markNotificationsRead,
|
|
67
77
|
resolveMentionedMembers,
|
|
68
78
|
unreadNotificationCount
|
|
69
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-RDTTK27V.js";
|
|
70
80
|
import {
|
|
71
81
|
applyReputation,
|
|
72
82
|
getReputationAdapter,
|
|
@@ -83,17 +93,9 @@ import {
|
|
|
83
93
|
resetProfanityAdapter,
|
|
84
94
|
setProfanityAdapter
|
|
85
95
|
} from "./chunk-KU5M27ZC.js";
|
|
86
|
-
import "./chunk-
|
|
87
|
-
import
|
|
88
|
-
|
|
89
|
-
getCommunityRole,
|
|
90
|
-
listCommunityRoles,
|
|
91
|
-
memberCan,
|
|
92
|
-
registerCommunityRole,
|
|
93
|
-
resetCommunityRoles,
|
|
94
|
-
withMemberWrite
|
|
95
|
-
} from "./chunk-PQBJWZ7D.js";
|
|
96
|
-
import "./chunk-S37WWNBB.js";
|
|
96
|
+
import "./chunk-2N53KKIL.js";
|
|
97
|
+
import "./chunk-6IEYOY2L.js";
|
|
98
|
+
import "./chunk-2VZZ7M26.js";
|
|
97
99
|
import "./chunk-EQ2Z3KMD.js";
|
|
98
100
|
import {
|
|
99
101
|
listAuditEvents,
|
|
@@ -104,16 +106,15 @@ import {
|
|
|
104
106
|
getCommunitySettings,
|
|
105
107
|
updateCommunitySettings,
|
|
106
108
|
validateCommunitySettingsPatch
|
|
107
|
-
} from "./chunk-
|
|
109
|
+
} from "./chunk-RKM4GDWM.js";
|
|
110
|
+
import "./chunk-P5WGQRSG.js";
|
|
108
111
|
import "./chunk-4ZLMEKFX.js";
|
|
109
112
|
import "./chunk-U4QCCLAW.js";
|
|
110
|
-
import "./chunk-ZCINJSS4.js";
|
|
111
113
|
import "./chunk-SBCVAC2Z.js";
|
|
114
|
+
import "./chunk-ZCINJSS4.js";
|
|
112
115
|
import "./chunk-LSHHRDVR.js";
|
|
113
|
-
import "./chunk-WV272MPW.js";
|
|
114
|
-
import "./chunk-CHQJG4BB.js";
|
|
115
|
-
import "./chunk-DWG3RZH2.js";
|
|
116
116
|
import "./chunk-V2UNHGAP.js";
|
|
117
|
+
import "./chunk-WV272MPW.js";
|
|
117
118
|
import "./chunk-OROPGO65.js";
|
|
118
119
|
import "./chunk-NFHS7CFV.js";
|
|
119
120
|
import "./chunk-XANPEOJC.js";
|