@classytic/repo-core 0.3.0 → 0.4.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/CHANGELOG.md +243 -0
- package/dist/_virtual/_rolldown/runtime.mjs +7 -0
- package/dist/adapter/index.d.mts +3 -0
- package/dist/adapter/index.mjs +2 -0
- package/dist/adapter/types.d.mts +222 -0
- package/dist/adapter/widen.d.mts +22 -0
- package/dist/adapter/widen.mjs +26 -0
- package/dist/aggregate/index.d.mts +3 -0
- package/dist/aggregate/index.mjs +3 -0
- package/dist/aggregate/keyset.d.mts +57 -0
- package/dist/aggregate/keyset.mjs +45 -0
- package/dist/aggregate/normalize.d.mts +24 -0
- package/dist/aggregate/normalize.mjs +28 -0
- package/dist/better-auth/index.d.mts +110 -0
- package/dist/better-auth/index.mjs +71 -0
- package/dist/cache/engine.d.mts +127 -0
- package/dist/cache/engine.mjs +235 -0
- package/dist/cache/envelope.mjs +32 -0
- package/dist/cache/index.d.mts +7 -2
- package/dist/cache/index.mjs +6 -2
- package/dist/cache/keys.mjs +131 -0
- package/dist/cache/memory-adapter.mjs +41 -7
- package/dist/cache/options.d.mts +112 -0
- package/dist/cache/options.mjs +25 -0
- package/dist/cache/plugin/context.d.mts +18 -0
- package/dist/cache/plugin/context.mjs +121 -0
- package/dist/cache/plugin/index.d.mts +86 -0
- package/dist/cache/plugin/index.mjs +78 -0
- package/dist/cache/plugin/invalidation-hooks.mjs +35 -0
- package/dist/cache/plugin/read-hooks.mjs +96 -0
- package/dist/cache/plugin/swr.mjs +20 -0
- package/dist/cache/runtime.d.mts +43 -0
- package/dist/cache/runtime.mjs +14 -0
- package/dist/cache/tag-index.mjs +84 -0
- package/dist/cache/timeout-adapter.d.mts +30 -0
- package/dist/cache/timeout-adapter.mjs +58 -0
- package/dist/cache/types.d.mts +45 -0
- package/dist/cache/version-store.mjs +57 -0
- package/dist/errors/index.d.mts +2 -1
- package/dist/errors/index.mjs +2 -1
- package/dist/errors/schema.d.mts +101 -0
- package/dist/errors/schema.mjs +78 -0
- package/dist/filter/match.mjs +38 -2
- package/dist/lock/index.d.mts +132 -0
- package/dist/lock/index.mjs +162 -0
- package/dist/pagination/canonical.d.mts +8 -8
- package/dist/pagination/canonical.mjs +3 -9
- package/dist/pagination/cursor.mjs +4 -1
- package/dist/pagination/index.d.mts +2 -2
- package/dist/pagination/types.d.mts +17 -27
- package/dist/plugins/index.d.mts +2 -0
- package/dist/plugins/index.mjs +2 -0
- package/dist/plugins/tenant-helpers.d.mts +63 -0
- package/dist/plugins/tenant-helpers.mjs +84 -0
- package/dist/query-parser/index.d.mts +2 -1
- package/dist/query-parser/index.mjs +2 -1
- package/dist/query-parser/parse-url.mjs +13 -11
- package/dist/query-parser/reserved.d.mts +43 -0
- package/dist/query-parser/reserved.mjs +56 -0
- package/dist/repository/agg-output.d.mts +63 -0
- package/dist/repository/agg-output.mjs +89 -0
- package/dist/repository/index.d.mts +4 -2
- package/dist/repository/index.mjs +3 -1
- package/dist/repository/options.d.mts +62 -0
- package/dist/repository/options.mjs +57 -0
- package/dist/repository/types.d.mts +936 -49
- package/dist/schema/field-rules.d.mts +41 -1
- package/dist/schema/field-rules.mjs +92 -1
- package/dist/schema/index.d.mts +2 -2
- package/dist/schema/index.mjs +2 -2
- package/dist/schema/types.d.mts +21 -0
- package/dist/testing/conformance.mjs +666 -17
- package/dist/testing/index.d.mts +3 -2
- package/dist/testing/index.mjs +2 -1
- package/dist/testing/lock-conformance.d.mts +25 -0
- package/dist/testing/lock-conformance.mjs +167 -0
- package/dist/testing/types.d.mts +99 -2
- package/package.json +23 -1
- package/dist/cache/stable-stringify.d.mts +0 -15
|
@@ -69,5 +69,45 @@ declare function isFieldUpdateAllowed(fieldName: string, options?: SchemaBuilder
|
|
|
69
69
|
* walking the rules themselves.
|
|
70
70
|
*/
|
|
71
71
|
declare function validateUpdateBody(body?: Record<string, unknown>, options?: SchemaBuilderOptions): ValidationResult;
|
|
72
|
+
/**
|
|
73
|
+
* Merge constraint-style `fieldRules` into a generated schema bag in place.
|
|
74
|
+
*
|
|
75
|
+
* Operates on the three slots that carry property maps — `createBody`,
|
|
76
|
+
* `updateBody`, `response`. `listQuery` and `params` are skipped (their
|
|
77
|
+
* constraint vocabulary is owned by the kit's query parser).
|
|
78
|
+
*
|
|
79
|
+
* Existing constraints on a property always win — the merge only fills in
|
|
80
|
+
* gaps. Kits that already walk `fieldRules` during base-schema assembly
|
|
81
|
+
* can call this helper for free (the checks are no-ops when constraints
|
|
82
|
+
* already exist).
|
|
83
|
+
*
|
|
84
|
+
* Schema slot type is intentionally loose (`Record<string, unknown> | null
|
|
85
|
+
* | undefined`) so adapters can pass either an `OpenApiSchemas`-shaped bag
|
|
86
|
+
* or a kit-native bag without coercion.
|
|
87
|
+
*/
|
|
88
|
+
declare function mergeFieldRuleConstraints(schemas: Record<string, unknown> | null | undefined, schemaOptions?: SchemaBuilderOptions): void;
|
|
89
|
+
/**
|
|
90
|
+
* Widen a JSON Schema property to also accept `null`.
|
|
91
|
+
*
|
|
92
|
+
* Handles the three ways a property can be typed:
|
|
93
|
+
* - `type: 'string'` → `type: ['string', 'null']`
|
|
94
|
+
* - `type: [...]` → append `'null'` if missing
|
|
95
|
+
* - `anyOf: [...]` → append `{ type: 'null' }` branch if missing
|
|
96
|
+
*
|
|
97
|
+
* **Enum interaction:** when the widened prop also carries `enum: [...]`,
|
|
98
|
+
* `null` is appended to the enum list too. AJV's `enum` keyword rejects
|
|
99
|
+
* values not in the list regardless of the widened `type`, so
|
|
100
|
+
* `{ type: ['string','null'], enum: ['a','b'] }` alone would still reject
|
|
101
|
+
* `null`. The fix is `enum: ['a','b', null]`. (The `anyOf` branch dodges
|
|
102
|
+
* this entirely — each branch scopes its own enum.)
|
|
103
|
+
*
|
|
104
|
+
* No-op when the schema already admits null (don't double-wrap) or has
|
|
105
|
+
* no `type` / `anyOf` anchor to widen (e.g. Mixed — already accepts null).
|
|
106
|
+
*
|
|
107
|
+
* Mutates in place — callers already treat the slot schema as owned.
|
|
108
|
+
* Exported so adapters that walk `fieldRules` inline can reuse the same
|
|
109
|
+
* widening logic.
|
|
110
|
+
*/
|
|
111
|
+
declare function applyNullable(prop: Record<string, unknown>): void;
|
|
72
112
|
//#endregion
|
|
73
|
-
export { applyFieldRules, collectFieldsToOmit, getImmutableFields, getSystemManagedFields, isFieldUpdateAllowed, validateUpdateBody };
|
|
113
|
+
export { applyFieldRules, applyNullable, collectFieldsToOmit, getImmutableFields, getSystemManagedFields, isFieldUpdateAllowed, mergeFieldRuleConstraints, validateUpdateBody };
|
|
@@ -126,5 +126,96 @@ function validateUpdateBody(body = {}, options = {}) {
|
|
|
126
126
|
violations
|
|
127
127
|
};
|
|
128
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Merge constraint-style `fieldRules` into a generated schema bag in place.
|
|
131
|
+
*
|
|
132
|
+
* Operates on the three slots that carry property maps — `createBody`,
|
|
133
|
+
* `updateBody`, `response`. `listQuery` and `params` are skipped (their
|
|
134
|
+
* constraint vocabulary is owned by the kit's query parser).
|
|
135
|
+
*
|
|
136
|
+
* Existing constraints on a property always win — the merge only fills in
|
|
137
|
+
* gaps. Kits that already walk `fieldRules` during base-schema assembly
|
|
138
|
+
* can call this helper for free (the checks are no-ops when constraints
|
|
139
|
+
* already exist).
|
|
140
|
+
*
|
|
141
|
+
* Schema slot type is intentionally loose (`Record<string, unknown> | null
|
|
142
|
+
* | undefined`) so adapters can pass either an `OpenApiSchemas`-shaped bag
|
|
143
|
+
* or a kit-native bag without coercion.
|
|
144
|
+
*/
|
|
145
|
+
function mergeFieldRuleConstraints(schemas, schemaOptions) {
|
|
146
|
+
if (!schemas || typeof schemas !== "object") return;
|
|
147
|
+
const rules = schemaOptions?.fieldRules;
|
|
148
|
+
if (!rules || Object.keys(rules).length === 0) return;
|
|
149
|
+
for (const slot of [
|
|
150
|
+
"createBody",
|
|
151
|
+
"updateBody",
|
|
152
|
+
"response"
|
|
153
|
+
]) {
|
|
154
|
+
const slotSchema = schemas[slot];
|
|
155
|
+
if (!slotSchema || typeof slotSchema !== "object") continue;
|
|
156
|
+
const properties = slotSchema["properties"];
|
|
157
|
+
if (!properties) continue;
|
|
158
|
+
for (const [field, rule] of Object.entries(rules)) {
|
|
159
|
+
const prop = properties[field];
|
|
160
|
+
if (!prop || typeof prop !== "object") continue;
|
|
161
|
+
if (rule.minLength != null && prop["minLength"] == null) prop["minLength"] = rule.minLength;
|
|
162
|
+
if (rule.maxLength != null && prop["maxLength"] == null) prop["maxLength"] = rule.maxLength;
|
|
163
|
+
if (rule.min != null && prop["minimum"] == null) prop["minimum"] = rule.min;
|
|
164
|
+
if (rule.max != null && prop["maximum"] == null) prop["maximum"] = rule.max;
|
|
165
|
+
if (rule.pattern != null && prop["pattern"] == null) prop["pattern"] = rule.pattern;
|
|
166
|
+
if (rule.enum != null && prop["enum"] == null) prop["enum"] = rule.enum;
|
|
167
|
+
if (rule.description != null && prop["description"] == null) prop["description"] = rule.description;
|
|
168
|
+
if (rule.nullable === true) applyNullable(prop);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Widen a JSON Schema property to also accept `null`.
|
|
174
|
+
*
|
|
175
|
+
* Handles the three ways a property can be typed:
|
|
176
|
+
* - `type: 'string'` → `type: ['string', 'null']`
|
|
177
|
+
* - `type: [...]` → append `'null'` if missing
|
|
178
|
+
* - `anyOf: [...]` → append `{ type: 'null' }` branch if missing
|
|
179
|
+
*
|
|
180
|
+
* **Enum interaction:** when the widened prop also carries `enum: [...]`,
|
|
181
|
+
* `null` is appended to the enum list too. AJV's `enum` keyword rejects
|
|
182
|
+
* values not in the list regardless of the widened `type`, so
|
|
183
|
+
* `{ type: ['string','null'], enum: ['a','b'] }` alone would still reject
|
|
184
|
+
* `null`. The fix is `enum: ['a','b', null]`. (The `anyOf` branch dodges
|
|
185
|
+
* this entirely — each branch scopes its own enum.)
|
|
186
|
+
*
|
|
187
|
+
* No-op when the schema already admits null (don't double-wrap) or has
|
|
188
|
+
* no `type` / `anyOf` anchor to widen (e.g. Mixed — already accepts null).
|
|
189
|
+
*
|
|
190
|
+
* Mutates in place — callers already treat the slot schema as owned.
|
|
191
|
+
* Exported so adapters that walk `fieldRules` inline can reuse the same
|
|
192
|
+
* widening logic.
|
|
193
|
+
*/
|
|
194
|
+
function applyNullable(prop) {
|
|
195
|
+
if (Array.isArray(prop["anyOf"])) {
|
|
196
|
+
if (!prop["anyOf"].some((b) => b !== null && typeof b === "object" && (b["type"] === "null" || b["const"] === null))) prop["anyOf"].push({ type: "null" });
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
if (Array.isArray(prop["type"])) {
|
|
200
|
+
if (!prop["type"].includes("null")) prop["type"].push("null");
|
|
201
|
+
widenEnumToIncludeNull(prop);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (typeof prop["type"] === "string") {
|
|
205
|
+
prop["type"] = [prop["type"], "null"];
|
|
206
|
+
widenEnumToIncludeNull(prop);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Append `null` to `enum` when present. Required because AJV's `enum`
|
|
212
|
+
* keyword is independent of `type` — a value must appear in the enum
|
|
213
|
+
* array verbatim even if the widened type says null is allowed.
|
|
214
|
+
*/
|
|
215
|
+
function widenEnumToIncludeNull(prop) {
|
|
216
|
+
if (!Array.isArray(prop["enum"])) return;
|
|
217
|
+
if (prop["enum"].includes(null)) return;
|
|
218
|
+
prop["enum"] = [...prop["enum"], null];
|
|
219
|
+
}
|
|
129
220
|
//#endregion
|
|
130
|
-
export { applyFieldRules, collectFieldsToOmit, getImmutableFields, getSystemManagedFields, isFieldUpdateAllowed, validateUpdateBody };
|
|
221
|
+
export { applyFieldRules, applyNullable, collectFieldsToOmit, getImmutableFields, getSystemManagedFields, isFieldUpdateAllowed, mergeFieldRuleConstraints, validateUpdateBody };
|
package/dist/schema/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { CrudSchemas, FieldRule, FieldRules, JsonSchema, SchemaBuilderOptions, ValidationResult } from "./types.mjs";
|
|
2
|
-
import { applyFieldRules, collectFieldsToOmit, getImmutableFields, getSystemManagedFields, isFieldUpdateAllowed, validateUpdateBody } from "./field-rules.mjs";
|
|
2
|
+
import { applyFieldRules, applyNullable, collectFieldsToOmit, getImmutableFields, getSystemManagedFields, isFieldUpdateAllowed, mergeFieldRuleConstraints, validateUpdateBody } from "./field-rules.mjs";
|
|
3
3
|
import { SchemaGenerator, SchemaGeneratorContext, isSchemaGenerator } from "./generator.mjs";
|
|
4
|
-
export { type CrudSchemas, type FieldRule, type FieldRules, type JsonSchema, type SchemaBuilderOptions, type SchemaGenerator, type SchemaGeneratorContext, type ValidationResult, applyFieldRules, collectFieldsToOmit, getImmutableFields, getSystemManagedFields, isFieldUpdateAllowed, isSchemaGenerator, validateUpdateBody };
|
|
4
|
+
export { type CrudSchemas, type FieldRule, type FieldRules, type JsonSchema, type SchemaBuilderOptions, type SchemaGenerator, type SchemaGeneratorContext, type ValidationResult, applyFieldRules, applyNullable, collectFieldsToOmit, getImmutableFields, getSystemManagedFields, isFieldUpdateAllowed, isSchemaGenerator, mergeFieldRuleConstraints, validateUpdateBody };
|
package/dist/schema/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { applyFieldRules, collectFieldsToOmit, getImmutableFields, getSystemManagedFields, isFieldUpdateAllowed, validateUpdateBody } from "./field-rules.mjs";
|
|
1
|
+
import { applyFieldRules, applyNullable, collectFieldsToOmit, getImmutableFields, getSystemManagedFields, isFieldUpdateAllowed, mergeFieldRuleConstraints, validateUpdateBody } from "./field-rules.mjs";
|
|
2
2
|
import { isSchemaGenerator } from "./generator.mjs";
|
|
3
|
-
export { applyFieldRules, collectFieldsToOmit, getImmutableFields, getSystemManagedFields, isFieldUpdateAllowed, isSchemaGenerator, validateUpdateBody };
|
|
3
|
+
export { applyFieldRules, applyNullable, collectFieldsToOmit, getImmutableFields, getSystemManagedFields, isFieldUpdateAllowed, isSchemaGenerator, mergeFieldRuleConstraints, validateUpdateBody };
|
package/dist/schema/types.d.mts
CHANGED
|
@@ -36,6 +36,27 @@ interface FieldRule {
|
|
|
36
36
|
* narrow on the same flag.
|
|
37
37
|
*/
|
|
38
38
|
hidden?: boolean;
|
|
39
|
+
/** String minimum length — JSON Schema `minLength`. */
|
|
40
|
+
minLength?: number;
|
|
41
|
+
/** String maximum length — JSON Schema `maxLength`. */
|
|
42
|
+
maxLength?: number;
|
|
43
|
+
/** Number minimum — JSON Schema `minimum`. */
|
|
44
|
+
min?: number;
|
|
45
|
+
/** Number maximum — JSON Schema `maximum`. */
|
|
46
|
+
max?: number;
|
|
47
|
+
/** Regex pattern — JSON Schema `pattern`. */
|
|
48
|
+
pattern?: string;
|
|
49
|
+
/** Allowed values — JSON Schema `enum`. */
|
|
50
|
+
enum?: ReadonlyArray<string | number>;
|
|
51
|
+
/**
|
|
52
|
+
* Widen the property type to also accept `null`. Implemented as a
|
|
53
|
+
* draft-07 type tuple (`type: ['string','null']`) or anyOf branch
|
|
54
|
+
* (`anyOf: [..., { type: 'null' }]`). Existing nullability is
|
|
55
|
+
* preserved — never double-widens.
|
|
56
|
+
*/
|
|
57
|
+
nullable?: boolean;
|
|
58
|
+
/** Human-readable description — JSON Schema `description`. */
|
|
59
|
+
description?: string;
|
|
39
60
|
}
|
|
40
61
|
/** Map of field name → FieldRule. */
|
|
41
62
|
interface FieldRules {
|