@cosmicdrift/kumiko-bundled-features 0.350.0 → 0.352.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audit/handlers/list.query.js +1 -1
- package/dist/auth-email-password/email-templates.js +1 -1
- package/dist/auth-email-password/handlers/invite-create.write.js +1 -1
- package/dist/auth-email-password/handlers/signup-request.write.js +1 -1
- package/dist/auth-email-password/handlers/token-request-handler.d.ts +1 -1
- package/dist/auth-email-password/reset-token.d.ts +1 -1
- package/dist/auth-email-password/unlock-token.d.ts +1 -1
- package/dist/auth-email-password/verification-token.d.ts +1 -1
- package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +1 -1
- package/dist/auth-mfa/handlers/enable-confirm.write.js +1 -1
- package/dist/auth-mfa/hmac-token-codec.d.ts +1 -1
- package/dist/auth-mfa/hmac-token-codec.js +1 -1
- package/dist/auth-mfa/mfa-challenge-token.d.ts +1 -1
- package/dist/auth-mfa/mfa-challenge-token.js +1 -1
- package/dist/auth-mfa/mfa-preauth-setup-token.d.ts +1 -1
- package/dist/auth-mfa/mfa-preauth-setup-token.js +1 -1
- package/dist/auth-mfa/mfa-setup-token.d.ts +1 -1
- package/dist/auth-mfa/mfa-setup-token.js +1 -1
- package/dist/billing-foundation/constants.d.ts +2 -2
- package/dist/billing-foundation/constants.js +3 -12
- package/dist/billing-foundation/consumer-protection/confirmation-mail.js +1 -1
- package/dist/billing-foundation/consumer-protection/termination-mail.js +1 -1
- package/dist/billing-foundation/feature.js +2 -9
- package/dist/billing-foundation/handlers/sync-subscription.write.js +3 -6
- package/dist/cap-counter/book-cap-usage.d.ts +5 -1
- package/dist/cap-counter/book-cap-usage.js +66 -45
- package/dist/cap-counter/cap-reservation.d.ts +12 -0
- package/dist/cap-counter/cap-reservation.js +135 -0
- package/dist/cap-counter/constants.d.ts +3 -0
- package/dist/cap-counter/constants.js +6 -0
- package/dist/cap-counter/enforce-cap.d.ts +1 -1
- package/dist/cap-counter/enforce-cap.js +1 -8
- package/dist/cap-counter/feature.js +7 -2
- package/dist/cap-counter/handlers/increment-rolling.write.d.ts +5 -0
- package/dist/cap-counter/handlers/increment-rolling.write.js +4 -0
- package/dist/cap-counter/index.d.ts +4 -2
- package/dist/cap-counter/index.js +3 -1
- package/dist/cap-counter/payload-field.d.ts +1 -0
- package/dist/cap-counter/payload-field.js +11 -0
- package/dist/cap-counter/reservation-chain.d.ts +2 -0
- package/dist/cap-counter/reservation-chain.js +44 -0
- package/dist/cap-counter/stock-cap-guard.d.ts +3 -0
- package/dist/cap-counter/tables.d.ts +3 -0
- package/dist/cap-counter/tables.js +36 -0
- package/dist/cap-counter/value-cap-guard.d.ts +18 -0
- package/dist/cap-counter/value-cap-guard.js +33 -0
- package/dist/cap-counter/with-cap-enforcement.d.ts +5 -7
- package/dist/cap-counter/with-cap-enforcement.js +35 -51
- package/dist/channel-discord/feature.js +1 -0
- package/dist/channel-slack/feature.js +1 -0
- package/dist/channel-teams/feature.js +1 -0
- package/dist/compliance-profiles/schema/profile-selection.d.ts +2 -0
- package/dist/delivery/attempt-log-retention.d.ts +9 -0
- package/dist/delivery/attempt-log-retention.js +23 -0
- package/dist/delivery/attempt-log.d.ts +1 -1
- package/dist/delivery/attempt-log.js +21 -2
- package/dist/delivery/constants.d.ts +1 -1
- package/dist/delivery/constants.js +1 -1
- package/dist/delivery/events.d.ts +1 -0
- package/dist/delivery/events.js +2 -0
- package/dist/delivery/feature.d.ts +1 -0
- package/dist/delivery/feature.js +39 -3
- package/dist/delivery/handlers/log.query.d.ts +1 -2
- package/dist/delivery/handlers/log.query.js +1 -1
- package/dist/delivery/index.d.ts +2 -1
- package/dist/delivery/index.js +2 -1
- package/dist/delivery/mask-recipient-address.d.ts +1 -0
- package/dist/delivery/mask-recipient-address.js +41 -0
- package/dist/delivery/public-names.d.ts +2 -0
- package/dist/delivery/public-names.js +3 -0
- package/dist/delivery/types.d.ts +1 -0
- package/dist/delivery/types.js +6 -2
- package/dist/feature-toggles/handlers/set.write.js +1 -1
- package/dist/form-draft/db/queries/cleanup.d.ts +1 -1
- package/dist/form-draft/db/queries/cleanup.js +1 -1
- package/dist/form-draft/db/queries/owned-file-refs.d.ts +1 -1
- package/dist/form-draft/lookup.d.ts +1 -1
- package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +1 -1
- package/dist/inbound-mail-foundation/oauth-access-token.d.ts +1 -1
- package/dist/inbound-mail-foundation/oauth-access-token.js +1 -1
- package/dist/inbound-mail-foundation/oauth-state.d.ts +1 -1
- package/dist/inbound-mail-foundation/oauth-state.js +1 -1
- package/dist/inbound-mail-foundation/watch-supervisor.js +1 -1
- package/dist/inbound-provider-imap/feature.js +1 -1
- package/dist/inbound-provider-imap/imap-client.js +1 -1
- package/dist/jobs/job-instant.d.ts +1 -1
- package/dist/jobs/job-instant.js +1 -1
- package/dist/ledger/entity.d.ts +3 -0
- package/dist/metrics/compute.d.ts +1 -1
- package/dist/metrics/feature.js +1 -1
- package/dist/metrics/types.d.ts +1 -1
- package/dist/metrics/window.d.ts +1 -1
- package/dist/metrics/window.js +1 -1
- package/dist/personal-access-tokens/expiry.js +1 -1
- package/dist/personal-access-tokens/handlers/create.write.js +1 -1
- package/dist/personal-access-tokens/handlers/revoke.write.js +1 -1
- package/dist/personal-access-tokens/revoke-for-user.js +1 -1
- package/dist/renderer-foundation/types.d.ts +1 -0
- package/dist/renderer-simple/feature.js +4 -6
- package/dist/renderer-simple/index.d.ts +1 -0
- package/dist/renderer-simple/mail-blocks.d.ts +21 -0
- package/dist/renderer-simple/mail-blocks.js +107 -0
- package/dist/renderer-simple/simple-renderer.js +21 -3
- package/dist/sessions/handlers/revoke-all-for-user.write.js +1 -1
- package/dist/sessions/handlers/revoke-all-others.write.js +1 -1
- package/dist/sessions/handlers/revoke.write.js +1 -1
- package/dist/sessions/session-callbacks.js +1 -1
- package/dist/shared/grace-period.d.ts +2 -1
- package/dist/shared/grace-period.js +3 -7
- package/dist/shared/row-bound-grant.d.ts +1 -1
- package/dist/shared/signed-token.d.ts +1 -1
- package/dist/shared/signed-token.js +1 -1
- package/dist/subscription-mollie/verify-webhook.js +1 -1
- package/dist/subscription-stripe/verify-webhook.js +1 -1
- package/dist/template-resolver/api.d.ts +1 -1
- package/dist/template-resolver/handlers/by-slug.query.d.ts +1 -1
- package/dist/template-resolver/handlers/by-tenant.query.d.ts +2 -2
- package/dist/template-resolver/handlers/collection-item.query.d.ts +1 -1
- package/dist/template-resolver/handlers/collection-list.query.d.ts +1 -1
- package/dist/template-resolver/handlers/collection-shared.d.ts +2 -2
- package/dist/template-resolver/handlers/find-by-id.query.d.ts +1 -1
- package/dist/template-resolver/handlers/list.query.d.ts +1 -1
- package/dist/template-resolver/table.d.ts +9 -1
- package/dist/template-resolver/user-content-table.d.ts +4 -0
- package/dist/tenant/handlers/team-list.query.d.ts +1 -1
- package/dist/tenant/handlers/team-list.query.js +1 -1
- package/dist/tenant/invitation-table.d.ts +2 -0
- package/dist/tenant/invited-membership.d.ts +1 -1
- package/dist/tenant/invited-membership.js +1 -1
- package/dist/tenant/schema/tenant.d.ts +2 -0
- package/dist/tenant-handover/grant.d.ts +1 -1
- package/dist/tier-engine/index.d.ts +1 -0
- package/dist/tier-engine/index.js +1 -0
- package/dist/tier-engine/tier-option-gate.d.ts +32 -0
- package/dist/tier-engine/tier-option-gate.js +62 -0
- package/dist/user/schema/user.d.ts +2 -0
- package/dist/user-data-rights/db/queries/export-jobs.d.ts +1 -1
- package/dist/user-data-rights/db/queries/forget-cleanup.d.ts +2 -2
- package/dist/user-data-rights/db/queries/forget-cleanup.js +2 -8
- package/dist/user-data-rights/deletion-token.d.ts +1 -1
- package/dist/user-data-rights/email-templates.js +1 -1
- package/dist/user-data-rights/handlers/list-download-attempts.query.js +1 -1
- package/dist/user-data-rights/handlers/my-audit-log.query.js +1 -1
- package/dist/user-data-rights/schema/export-job.d.ts +2 -0
- package/dist/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.js +25 -6
- package/dist/waitlist/entity.d.ts +2 -0
- package/dist/waitlist/handlers/invite.write.js +1 -1
- package/dist/waitlist/handlers/submit.write.js +1 -1
- package/package.json +10 -10
- package/src/cap-counter/changes.json +28 -0
- package/src/delivery/changes.json +12 -0
- package/src/derivatives-sharp/changes.json +6 -0
- package/src/legal-pages/changes.json +6 -0
- package/src/renderer-simple/changes.json +6 -0
- package/src/tier-engine/changes.json +6 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Tier-gated options of a select field: one spec drives the availability query the
|
|
2
|
+
// renderer shows (disabled option + "from <tier>" hint) and the write-path check that
|
|
3
|
+
// actually enforces it, so the two cannot drift apart.
|
|
4
|
+
import { UnprocessableError, writeFailure, } from "@cosmicdrift/kumiko-framework/errors";
|
|
5
|
+
import { isPlainObject } from "@cosmicdrift/kumiko-framework/utils";
|
|
6
|
+
import { readPayloadField, } from "../cap-counter/index.js";
|
|
7
|
+
function limitContextOf(ctx) {
|
|
8
|
+
return ctx.config ? { config: ctx.config } : {};
|
|
9
|
+
}
|
|
10
|
+
function recordIdOf(payload) {
|
|
11
|
+
return isPlainObject(payload) && typeof payload["id"] === "string" ? payload["id"] : undefined;
|
|
12
|
+
}
|
|
13
|
+
export function createTierOptionGate(deps) {
|
|
14
|
+
async function capsPerTier(context) {
|
|
15
|
+
return Promise.all(deps.tierOrder.map(async (tier) => ({ tier, caps: await deps.capsForTier(tier, context) })));
|
|
16
|
+
}
|
|
17
|
+
async function optionAvailability(db, context, spec, hintFor) {
|
|
18
|
+
const currentCaps = await deps.capsForTier(await deps.resolveTier(db), context);
|
|
19
|
+
const tiers = await capsPerTier(context);
|
|
20
|
+
return spec.options.map((value) => {
|
|
21
|
+
if (spec.isOptionAllowed(value, currentCaps))
|
|
22
|
+
return { value, disabled: false };
|
|
23
|
+
const required = tiers.find(({ caps }) => spec.isOptionAllowed(value, caps));
|
|
24
|
+
return required === undefined
|
|
25
|
+
? { value, disabled: true }
|
|
26
|
+
: { value, disabled: true, hint: hintFor(required.tier) };
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async function storedValueMatches(ctx, spec, value, recordId) {
|
|
30
|
+
if (spec.table === undefined || recordId === undefined)
|
|
31
|
+
return false;
|
|
32
|
+
const stored = await ctx.db.fetchOne(spec.table, { id: recordId });
|
|
33
|
+
return stored?.[spec.field] === value;
|
|
34
|
+
}
|
|
35
|
+
async function checkTierOption(ctx, value, spec, recordId) {
|
|
36
|
+
// skip: an absent or non-string value is the schema's business, not a tier violation.
|
|
37
|
+
if (typeof value !== "string")
|
|
38
|
+
return null;
|
|
39
|
+
const context = limitContextOf(ctx);
|
|
40
|
+
const currentCaps = await deps.capsForTier(await deps.resolveTier(ctx.db), context);
|
|
41
|
+
if (spec.isOptionAllowed(value, currentCaps))
|
|
42
|
+
return null;
|
|
43
|
+
if (await storedValueMatches(ctx, spec, value, recordId))
|
|
44
|
+
return null;
|
|
45
|
+
const required = (await capsPerTier(context)).find(({ caps }) => spec.isOptionAllowed(value, caps));
|
|
46
|
+
return writeFailure(new UnprocessableError(spec.code, {
|
|
47
|
+
i18nKey: spec.i18nKey,
|
|
48
|
+
details: { field: spec.field, value, requiredTier: required?.tier },
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
function withTierOptionGate(handler, spec) {
|
|
52
|
+
return {
|
|
53
|
+
...handler,
|
|
54
|
+
handler: async (event, ctx) => {
|
|
55
|
+
const value = readPayloadField(event.payload, spec.field);
|
|
56
|
+
const failure = await checkTierOption(ctx, value, spec, recordIdOf(event.payload));
|
|
57
|
+
return failure ?? handler.handler(event, ctx);
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return { optionAvailability, checkTierOption, withTierOptionGate };
|
|
62
|
+
}
|
|
@@ -165,6 +165,7 @@ export declare const userEntity: import("@cosmicdrift/kumiko-types/fields").Enti
|
|
|
165
165
|
} | undefined;
|
|
166
166
|
readonly optionsQuery?: string;
|
|
167
167
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
168
|
+
readonly optionsAvailabilityQuery?: string;
|
|
168
169
|
} & import("@cosmicdrift/kumiko-types/fields").ResolvedPiiFlags & {
|
|
169
170
|
required: true;
|
|
170
171
|
};
|
|
@@ -343,6 +344,7 @@ export declare const userTable: import("@cosmicdrift/kumiko-framework/db").Entit
|
|
|
343
344
|
} | undefined;
|
|
344
345
|
readonly optionsQuery?: string;
|
|
345
346
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
347
|
+
readonly optionsAvailabilityQuery?: string;
|
|
346
348
|
} & import("@cosmicdrift/kumiko-types/fields").ResolvedPiiFlags & {
|
|
347
349
|
required: true;
|
|
348
350
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
|
-
import type { Temporal } from "temporal
|
|
3
|
+
import type { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
4
4
|
export type ExportJobCleanupCandidate = {
|
|
5
5
|
readonly id: string;
|
|
6
6
|
readonly version: number;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DbConnection } from "@cosmicdrift/kumiko-framework/db";
|
|
2
|
-
import { Temporal
|
|
3
|
-
export declare function selectUsersDueForForgetCleanup(db: DbConnection, status: string, gracePeriodEndCutoff:
|
|
2
|
+
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
3
|
+
export declare function selectUsersDueForForgetCleanup(db: DbConnection, status: string, gracePeriodEndCutoff: Temporal.Instant | string): Promise<readonly {
|
|
4
4
|
id: string;
|
|
5
5
|
}[]>;
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
2
|
-
|
|
3
|
-
// `Temporal` TYPE that gracePeriodEndCutoff's parameter type resolves
|
|
4
|
-
// against (same #1438 dual-package-hazard pattern as event-store.ts).
|
|
5
|
-
import { Temporal as TemporalPolyfill } from "temporal-polyfill";
|
|
2
|
+
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
6
3
|
import { userTable } from "../../../user/index.js";
|
|
7
4
|
export async function selectUsersDueForForgetCleanup(db, status, gracePeriodEndCutoff) {
|
|
8
|
-
// @cast-boundary temporal-polyfill-vs-ambient: same TC39 Temporal.Instant
|
|
9
|
-
// at runtime, distinct nominal types across the two .d.ts sources (see
|
|
10
|
-
// event-store.ts). Only ever consumed via the `lte` comparison below.
|
|
11
5
|
const cutoff = typeof gracePeriodEndCutoff === "string"
|
|
12
|
-
?
|
|
6
|
+
? Temporal.Instant.from(gracePeriodEndCutoff)
|
|
13
7
|
: gracePeriodEndCutoff;
|
|
14
8
|
return selectMany(db, userTable, {
|
|
15
9
|
status,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Temporal } from "temporal
|
|
1
|
+
import type { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
2
2
|
import { type RowBoundGrantResult } from "../shared/index.js";
|
|
3
3
|
export declare function signDeletionToken(userId: string, requestId: string, ttlMinutes: number, secret: string, now?: Temporal.Instant): {
|
|
4
4
|
readonly token: string;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// branding pass send*Email callbacks and these defaults do not run.
|
|
5
5
|
import { mailT, registerMailTranslations } from "@cosmicdrift/kumiko-framework/i18n";
|
|
6
6
|
import { escapeHtml, escapeHtmlAttr } from "@cosmicdrift/kumiko-headless";
|
|
7
|
-
import { Temporal } from "temporal
|
|
7
|
+
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
8
8
|
export function normalizeGdprMailLocale(raw) {
|
|
9
9
|
if (!raw)
|
|
10
10
|
return undefined;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
2
2
|
import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
|
-
import { Temporal } from "temporal
|
|
3
|
+
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
4
4
|
import * as z from "zod";
|
|
5
5
|
import { downloadAttemptsTable } from "../schema/download-attempt.js";
|
|
6
6
|
// Operator-Query: invalid Download-Attempts (S2.U7).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
2
2
|
import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import { eventsTable } from "@cosmicdrift/kumiko-framework/event-store";
|
|
4
|
-
import { Temporal } from "temporal
|
|
4
|
+
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
5
5
|
import * as z from "zod";
|
|
6
6
|
// DSGVO Art. 15 Selbstauskunft — User reads HIS OWN audit-log.
|
|
7
7
|
// WHERE createdBy = ctx.user.id ist hard-coded (kein userId-Param,
|
|
@@ -74,6 +74,7 @@ export declare const exportJobEntity: import("@cosmicdrift/kumiko-types/fields")
|
|
|
74
74
|
} | undefined;
|
|
75
75
|
readonly optionsQuery?: string;
|
|
76
76
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
77
|
+
readonly optionsAvailabilityQuery?: string;
|
|
77
78
|
} & import("@cosmicdrift/kumiko-types/fields").ResolvedPiiFlags & {
|
|
78
79
|
required: true;
|
|
79
80
|
};
|
|
@@ -249,6 +250,7 @@ export declare const exportJobsTable: import("@cosmicdrift/kumiko-framework/db")
|
|
|
249
250
|
} | undefined;
|
|
250
251
|
readonly optionsQuery?: string;
|
|
251
252
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
253
|
+
readonly optionsAvailabilityQuery?: string;
|
|
252
254
|
} & import("@cosmicdrift/kumiko-types/fields").ResolvedPiiFlags & {
|
|
253
255
|
required: true;
|
|
254
256
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { appendEventInTenantDb, getStreamVersionInTenantDb, } from "@cosmicdrift/kumiko-framework/event-store";
|
|
2
|
+
import { DELIVERY_ATTEMPT_ADDRESS_ERASED_EVENT, deliveryAttemptsTable, } from "../../delivery/index.js";
|
|
2
3
|
import { featureMounted } from "./feature-mounted.js";
|
|
3
4
|
// userData-Hooks for delivery's attempt log (deferred from #797, closed by
|
|
4
5
|
// #799). deliveryAttempt is an events-only aggregate — the export reads the
|
|
@@ -26,9 +27,27 @@ export const deliveryAttemptExportHook = async (ctx) => {
|
|
|
26
27
|
})),
|
|
27
28
|
};
|
|
28
29
|
};
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
//
|
|
30
|
+
// Both strategies erase the address. The DEK shredding of a forget covers KMS deployments; the
|
|
31
|
+
// erase event also covers plaintext mode, and unlike a read-side UPDATE it survives a projection
|
|
32
|
+
// rebuild. Rows without an address are skipped, which makes a second run a no-op.
|
|
33
|
+
export const deliveryAttemptDeleteHook = async (ctx) => {
|
|
34
|
+
// skip: delivery not mounted — its table doesn't exist, nothing to erase.
|
|
35
|
+
if (!featureMounted(ctx, "delivery"))
|
|
36
|
+
return;
|
|
37
|
+
const rows = await ctx.db.selectMany(deliveryAttemptsTable, {
|
|
38
|
+
tenantId: ctx.tenantId,
|
|
39
|
+
recipientId: ctx.userId,
|
|
40
|
+
});
|
|
41
|
+
for (const row of rows) {
|
|
42
|
+
if (row.recipientAddress === null)
|
|
43
|
+
continue;
|
|
44
|
+
await appendEventInTenantDb(ctx.db, {
|
|
45
|
+
aggregateType: "deliveryAttempt",
|
|
46
|
+
aggregateId: row.id,
|
|
47
|
+
expectedVersion: await getStreamVersionInTenantDb(ctx.db, row.id),
|
|
48
|
+
type: DELIVERY_ATTEMPT_ADDRESS_ERASED_EVENT,
|
|
49
|
+
payload: {},
|
|
50
|
+
metadata: { userId: "system" },
|
|
51
|
+
}, { registry: ctx.registry });
|
|
52
|
+
}
|
|
34
53
|
};
|
|
@@ -139,6 +139,7 @@ export declare const waitlistEntryEntity: import("@cosmicdrift/kumiko-types/fiel
|
|
|
139
139
|
} | undefined;
|
|
140
140
|
readonly optionsQuery?: string;
|
|
141
141
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
142
|
+
readonly optionsAvailabilityQuery?: string;
|
|
142
143
|
} & import("@cosmicdrift/kumiko-types/fields").ResolvedPiiFlags & {
|
|
143
144
|
required: true;
|
|
144
145
|
};
|
|
@@ -355,6 +356,7 @@ export declare const waitlistEntryTable: import("@cosmicdrift/kumiko-framework/d
|
|
|
355
356
|
} | undefined;
|
|
356
357
|
readonly optionsQuery?: string;
|
|
357
358
|
readonly optionsQueryPayload?: import("@cosmicdrift/kumiko-types/fields").OptionsQueryPayload;
|
|
359
|
+
readonly optionsAvailabilityQuery?: string;
|
|
358
360
|
} & import("@cosmicdrift/kumiko-types/fields").ResolvedPiiFlags & {
|
|
359
361
|
required: true;
|
|
360
362
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
|
|
2
2
|
import { createSystemUser, defineWriteHandler, parseTenantId, } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import { InternalError, NotFoundError, UnprocessableError, writeFailure, } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
|
-
import { Temporal } from "temporal
|
|
4
|
+
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
5
5
|
import { AuthErrors, AuthHandlers } from "../../auth-email-password/index.js";
|
|
6
6
|
import { TenantHandlers, tenantTable } from "../../tenant/index.js";
|
|
7
7
|
import { DEFAULT_OWN_TENANT_INVITE_ROLE, WAITLIST_STATUS, WaitlistErrors } from "../constants.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { acquireNamespacedAdvisoryLock } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { access, defineWriteHandler, } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
|
-
import { Temporal } from "temporal
|
|
4
|
+
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
5
5
|
import { WAITLIST_NOTIFICATION_TYPES, WAITLIST_STATUS } from "../constants.js";
|
|
6
6
|
import { normalizeEmail, platformActor, waitlistDb, waitlistExecutor } from "../lib.js";
|
|
7
7
|
import { renderWaitlistAdminNoticeEmail, renderWaitlistConfirmationEmail, resolveWaitlistAdminMailLocale, resolveWaitlistMailLocale, } from "../mail.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-bundled-features",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.352.0",
|
|
4
4
|
"description": "Built-in features — tenant, user, auth, delivery. The stuff you'd rewrite anyway, already typed.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -503,12 +503,12 @@
|
|
|
503
503
|
}
|
|
504
504
|
},
|
|
505
505
|
"dependencies": {
|
|
506
|
-
"@cosmicdrift/kumiko-dispatcher-live": "0.
|
|
507
|
-
"@cosmicdrift/kumiko-framework": "0.
|
|
508
|
-
"@cosmicdrift/kumiko-headless": "0.
|
|
509
|
-
"@cosmicdrift/kumiko-renderer": "0.
|
|
510
|
-
"@cosmicdrift/kumiko-renderer-web": "0.
|
|
511
|
-
"@cosmicdrift/kumiko-types": "0.
|
|
506
|
+
"@cosmicdrift/kumiko-dispatcher-live": "0.352.0",
|
|
507
|
+
"@cosmicdrift/kumiko-framework": "0.352.0",
|
|
508
|
+
"@cosmicdrift/kumiko-headless": "0.352.0",
|
|
509
|
+
"@cosmicdrift/kumiko-renderer": "0.352.0",
|
|
510
|
+
"@cosmicdrift/kumiko-renderer-web": "0.352.0",
|
|
511
|
+
"@cosmicdrift/kumiko-types": "0.352.0",
|
|
512
512
|
"@mollie/api-client": "^4.5.0",
|
|
513
513
|
"@node-rs/argon2": "^2.0.2",
|
|
514
514
|
"@types/mailparser": "^3.4.6",
|
|
@@ -524,7 +524,7 @@
|
|
|
524
524
|
"nodemailer": "^10.0.13",
|
|
525
525
|
"qrcode": "^1.5.4",
|
|
526
526
|
"react": "^19.2.6",
|
|
527
|
-
"sharp": "^0.35.
|
|
527
|
+
"sharp": "^0.35.5",
|
|
528
528
|
"stripe": "^22.6.2",
|
|
529
529
|
"tailwind-merge": "^3.6.0",
|
|
530
530
|
"temporal-polyfill": "^0.3.2",
|
|
@@ -1025,8 +1025,8 @@
|
|
|
1025
1025
|
],
|
|
1026
1026
|
"devDependencies": {
|
|
1027
1027
|
"@testing-library/user-event": "^14.6.1",
|
|
1028
|
-
"@cosmicdrift/kumiko-locale-de": "0.
|
|
1029
|
-
"@cosmicdrift/kumiko-locale-es": "0.
|
|
1028
|
+
"@cosmicdrift/kumiko-locale-de": "0.352.0",
|
|
1029
|
+
"@cosmicdrift/kumiko-locale-es": "0.352.0",
|
|
1030
1030
|
"jsqr": "^1.4.0"
|
|
1031
1031
|
}
|
|
1032
1032
|
}
|
|
@@ -1,4 +1,32 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.352.0",
|
|
4
|
+
"type": "breaking",
|
|
5
|
+
"title": "Calendar cap reservations are stored in the new store_cap_reservations table",
|
|
6
|
+
"detail": "Capped writes now insert and delete rows in store_cap_reservations, so they fail until the table exists.",
|
|
7
|
+
"migration": "Generate and apply a migration with `kumiko-schema generate` — capped writes fail without the new store_cap_reservations table"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"version": "0.352.0",
|
|
11
|
+
"type": "improvement",
|
|
12
|
+
"title": "Reservations expire after 60 minutes and are swept before the next reserve of the same cap"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"version": "0.352.0",
|
|
16
|
+
"type": "fix",
|
|
17
|
+
"title": "withCapEnforcement keeps the wrapped handler's settings (rateLimit, additionalRateLimits) and composes with an inner reserveBeforeTransaction"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"version": "0.352.0",
|
|
21
|
+
"type": "improvement",
|
|
22
|
+
"title": "withRollingCapEnforcement reserves before the handler transaction and releases through the new rolling-released event, so rejected or failed writes no longer consume rolling cap"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"version": "0.352.0",
|
|
26
|
+
"type": "improvement",
|
|
27
|
+
"title": "createValueCapGuard rejects a written number outside the min and max of the tenant's tier",
|
|
28
|
+
"detail": "A number written by a handler can be bounded per tier\n`createValueCapGuard(resolveTierCaps)` returns `checkValueCap` and `withValueCap`. The spec names the payload field, optional `min` and `max` functions over the tier caps (`undefined` means unbounded), an error code and an i18n key. The value is read from the payload or, for entity updates, from `changes`; an absent or non-numeric value passes. A value below the minimum or above the maximum is rejected with `UnprocessableError` and `details: { field, value, min, max }`. `withValueCap` spreads the wrapped handler, so it composes with `withCapEnforcement`."
|
|
29
|
+
},
|
|
2
30
|
{
|
|
3
31
|
"version": "0.348.0",
|
|
4
32
|
"type": "fix",
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.352.0",
|
|
4
|
+
"type": "breaking",
|
|
5
|
+
"title": "Delivery attempt log stores masked recipient addresses; attempts older than 90 days are pruned",
|
|
6
|
+
"detail": "The log query, the export and the stored events show masked addresses, and the feature registers the daily attempt-log-retention job.",
|
|
7
|
+
"migration": "Read recipients from your own data, not from the attempt log, because it only shows masked addresses now. Set `attemptLogRetentionDays` on createDeliveryFeature to another number of days, or to `false` to keep the log, if 90 days does not fit. Schedule nothing extra, the feature registers the cron job itself. Existing full-address entries are removed by the retention job once they are older than the window, or erased when their user is forgotten."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"version": "0.352.0",
|
|
11
|
+
"type": "improvement",
|
|
12
|
+
"title": "Forgetting a user erases the recipient address of their delivery attempts in plaintext mode too, through an event that survives projection rebuilds"
|
|
13
|
+
},
|
|
2
14
|
{
|
|
3
15
|
"version": "0.343.0",
|
|
4
16
|
"type": "improvement",
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.352.0",
|
|
4
|
+
"type": "fix",
|
|
5
|
+
"title": "The legal-pages README imprint example uses a fictional demo identity",
|
|
6
|
+
"detail": "The legal-pages README seeds its imprint example with a fictional demo identity and address instead of a real person's details."
|
|
7
|
+
},
|
|
2
8
|
{
|
|
3
9
|
"version": "0.344.0",
|
|
4
10
|
"type": "improvement",
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.352.0",
|
|
4
|
+
"type": "improvement",
|
|
5
|
+
"title": "Badge, stages track and chips for the simple mail renderer",
|
|
6
|
+
"detail": "Use badge, { stages } and { chips } in the template variables; the notification RenderResponse carries the matching plain text in text."
|
|
7
|
+
},
|
|
2
8
|
{
|
|
3
9
|
"version": "0.344.0",
|
|
4
10
|
"type": "improvement",
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.352.0",
|
|
4
|
+
"type": "improvement",
|
|
5
|
+
"title": "createTierOptionGate builds the availability rows and gates select options by tier on write",
|
|
6
|
+
"detail": "withTierOptionGate rejects a disallowed option with the lowest tier that allows it and lets an unchanged stored value pass on update."
|
|
7
|
+
},
|
|
2
8
|
{
|
|
3
9
|
"version": "0.278.0",
|
|
4
10
|
"type": "breaking",
|