ultimabase 0.0.0-stage → 0.1.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/CHANGELOG.md +7 -0
- package/README.md +4 -2
- package/dist/access.d.ts +62 -0
- package/dist/access.d.ts.map +1 -0
- package/dist/access.js +258 -0
- package/dist/adapter-errors.d.ts +43 -0
- package/dist/adapter-errors.d.ts.map +1 -0
- package/dist/adapter-errors.js +72 -0
- package/dist/adapter-json.d.ts +20 -0
- package/dist/adapter-json.d.ts.map +1 -0
- package/dist/adapter-json.js +2 -0
- package/dist/adapter-migrations.d.ts +90 -0
- package/dist/adapter-migrations.d.ts.map +1 -0
- package/dist/adapter-migrations.js +1 -0
- package/dist/adapter.d.ts +333 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +5 -0
- package/dist/aggregate.d.ts +31 -0
- package/dist/aggregate.d.ts.map +1 -0
- package/dist/aggregate.js +99 -0
- package/dist/app-internals.d.ts +10 -0
- package/dist/app-internals.d.ts.map +1 -0
- package/dist/app-internals.js +12 -0
- package/dist/app-options.d.ts +22 -0
- package/dist/app-options.d.ts.map +1 -0
- package/dist/app-options.js +3 -0
- package/dist/cascade.d.ts +47 -0
- package/dist/cascade.d.ts.map +1 -0
- package/dist/cascade.js +209 -0
- package/dist/cli-config.d.ts +6 -0
- package/dist/cli-config.d.ts.map +1 -0
- package/dist/cli-config.js +45 -0
- package/dist/cli-deploy.d.ts +14 -0
- package/dist/cli-deploy.d.ts.map +1 -0
- package/dist/cli-deploy.js +193 -0
- package/dist/cli-main.d.ts +16 -0
- package/dist/cli-main.d.ts.map +1 -0
- package/dist/cli-main.js +151 -0
- package/dist/cli-migrate.d.ts +20 -0
- package/dist/cli-migrate.d.ts.map +1 -0
- package/dist/cli-migrate.js +105 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +4 -0
- package/dist/complete.d.ts +13 -0
- package/dist/complete.d.ts.map +1 -0
- package/dist/complete.js +60 -0
- package/dist/console-logger.d.ts +3 -0
- package/dist/console-logger.d.ts.map +1 -0
- package/dist/console-logger.js +62 -0
- package/dist/create-many.d.ts +7 -0
- package/dist/create-many.d.ts.map +1 -0
- package/dist/create-many.js +88 -0
- package/dist/decimal.d.ts +23 -0
- package/dist/decimal.d.ts.map +1 -0
- package/dist/decimal.js +50 -0
- package/dist/define-app.d.ts +59 -0
- package/dist/define-app.d.ts.map +1 -0
- package/dist/define-app.js +5 -0
- package/dist/define-enum.d.ts +6 -0
- package/dist/define-enum.d.ts.map +1 -0
- package/dist/define-enum.js +18 -0
- package/dist/define-function.d.ts +25 -0
- package/dist/define-function.d.ts.map +1 -0
- package/dist/define-function.js +111 -0
- package/dist/define-model.d.ts +48 -0
- package/dist/define-model.d.ts.map +1 -0
- package/dist/define-model.js +85 -0
- package/dist/definition.d.ts +179 -0
- package/dist/definition.d.ts.map +1 -0
- package/dist/definition.js +165 -0
- package/dist/delete-many.d.ts +13 -0
- package/dist/delete-many.d.ts.map +1 -0
- package/dist/delete-many.js +58 -0
- package/dist/engine.d.ts +16 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +174 -0
- package/dist/errors.d.ts +50 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +43 -0
- package/dist/exact.d.ts +20 -0
- package/dist/exact.d.ts.map +1 -0
- package/dist/exact.js +1 -0
- package/dist/feed.d.ts +6 -0
- package/dist/feed.d.ts.map +1 -0
- package/dist/feed.js +33 -0
- package/dist/field-codec.d.ts +11 -0
- package/dist/field-codec.d.ts.map +1 -0
- package/dist/field-codec.js +48 -0
- package/dist/field-rules.d.ts +57 -0
- package/dist/field-rules.d.ts.map +1 -0
- package/dist/field-rules.js +1 -0
- package/dist/field-type.d.ts +51 -0
- package/dist/field-type.d.ts.map +1 -0
- package/dist/field-type.js +106 -0
- package/dist/fields.d.ts +295 -0
- package/dist/fields.d.ts.map +1 -0
- package/dist/fields.js +1 -0
- package/dist/function.d.ts +126 -0
- package/dist/function.d.ts.map +1 -0
- package/dist/function.js +1 -0
- package/dist/functions.d.ts +18 -0
- package/dist/functions.d.ts.map +1 -0
- package/dist/functions.js +99 -0
- package/dist/group-by.d.ts +10 -0
- package/dist/group-by.d.ts.map +1 -0
- package/dist/group-by.js +145 -0
- package/dist/group-having.d.ts +8 -0
- package/dist/group-having.d.ts.map +1 -0
- package/dist/group-having.js +97 -0
- package/dist/hooks.d.ts +41 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +149 -0
- package/dist/hosts.d.ts +3 -0
- package/dist/hosts.d.ts.map +1 -0
- package/dist/hosts.js +8 -0
- package/dist/identify.d.ts +15 -0
- package/dist/identify.d.ts.map +1 -0
- package/dist/identify.js +71 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/internal.d.ts +28 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +39 -0
- package/dist/lifecycle.d.ts +21 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +149 -0
- package/dist/list-update.d.ts +12 -0
- package/dist/list-update.d.ts.map +1 -0
- package/dist/list-update.js +52 -0
- package/dist/live.d.ts +37 -0
- package/dist/live.d.ts.map +1 -0
- package/dist/live.js +139 -0
- package/dist/manifest.d.ts +11 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +60 -0
- package/dist/memory-aggregate.d.ts +7 -0
- package/dist/memory-aggregate.d.ts.map +1 -0
- package/dist/memory-aggregate.js +107 -0
- package/dist/memory-conditions.d.ts +8 -0
- package/dist/memory-conditions.d.ts.map +1 -0
- package/dist/memory-conditions.js +82 -0
- package/dist/memory-draft.d.ts +34 -0
- package/dist/memory-draft.d.ts.map +1 -0
- package/dist/memory-draft.js +255 -0
- package/dist/memory-json.d.ts +6 -0
- package/dist/memory-json.d.ts.map +1 -0
- package/dist/memory-json.js +86 -0
- package/dist/memory-read.d.ts +45 -0
- package/dist/memory-read.d.ts.map +1 -0
- package/dist/memory-read.js +244 -0
- package/dist/memory-search.d.ts +16 -0
- package/dist/memory-search.d.ts.map +1 -0
- package/dist/memory-search.js +110 -0
- package/dist/memory-values.d.ts +23 -0
- package/dist/memory-values.d.ts.map +1 -0
- package/dist/memory-values.js +82 -0
- package/dist/memory.d.ts +4 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +157 -0
- package/dist/migrate.d.ts +22 -0
- package/dist/migrate.d.ts.map +1 -0
- package/dist/migrate.js +131 -0
- package/dist/model.d.ts +239 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +1 -0
- package/dist/nested-write.d.ts +64 -0
- package/dist/nested-write.d.ts.map +1 -0
- package/dist/nested-write.js +274 -0
- package/dist/number-update.d.ts +18 -0
- package/dist/number-update.d.ts.map +1 -0
- package/dist/number-update.js +96 -0
- package/dist/plugin-app.d.ts +48 -0
- package/dist/plugin-app.d.ts.map +1 -0
- package/dist/plugin-app.js +230 -0
- package/dist/plugin-code.d.ts +17 -0
- package/dist/plugin-code.d.ts.map +1 -0
- package/dist/plugin-code.js +125 -0
- package/dist/plugin-use.d.ts +22 -0
- package/dist/plugin-use.d.ts.map +1 -0
- package/dist/plugin-use.js +161 -0
- package/dist/plugin.d.ts +357 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +17 -0
- package/dist/query-aggregate.d.ts +82 -0
- package/dist/query-aggregate.d.ts.map +1 -0
- package/dist/query-aggregate.js +1 -0
- package/dist/query-args.d.ts +41 -0
- package/dist/query-args.d.ts.map +1 -0
- package/dist/query-args.js +263 -0
- package/dist/query-bulk.d.ts +35 -0
- package/dist/query-bulk.d.ts.map +1 -0
- package/dist/query-bulk.js +1 -0
- package/dist/query-conditions.d.ts +9 -0
- package/dist/query-conditions.d.ts.map +1 -0
- package/dist/query-conditions.js +46 -0
- package/dist/query-context.d.ts +32 -0
- package/dist/query-context.d.ts.map +1 -0
- package/dist/query-context.js +55 -0
- package/dist/query-filter.d.ts +46 -0
- package/dist/query-filter.d.ts.map +1 -0
- package/dist/query-filter.js +1 -0
- package/dist/query-group.d.ts +82 -0
- package/dist/query-group.d.ts.map +1 -0
- package/dist/query-group.js +1 -0
- package/dist/query-json.d.ts +9 -0
- package/dist/query-json.d.ts.map +1 -0
- package/dist/query-json.js +66 -0
- package/dist/query-order.d.ts +15 -0
- package/dist/query-order.d.ts.map +1 -0
- package/dist/query-order.js +115 -0
- package/dist/query-project.d.ts +15 -0
- package/dist/query-project.d.ts.map +1 -0
- package/dist/query-project.js +45 -0
- package/dist/query-search.d.ts +24 -0
- package/dist/query-search.d.ts.map +1 -0
- package/dist/query-search.js +2 -0
- package/dist/query-values.d.ts +28 -0
- package/dist/query-values.d.ts.map +1 -0
- package/dist/query-values.js +91 -0
- package/dist/query-where.d.ts +46 -0
- package/dist/query-where.d.ts.map +1 -0
- package/dist/query-where.js +200 -0
- package/dist/query-write.d.ts +14 -0
- package/dist/query-write.d.ts.map +1 -0
- package/dist/query-write.js +260 -0
- package/dist/query.d.ts +254 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +1 -0
- package/dist/record.d.ts +257 -0
- package/dist/record.d.ts.map +1 -0
- package/dist/record.js +1 -0
- package/dist/recorder.d.ts +32 -0
- package/dist/recorder.d.ts.map +1 -0
- package/dist/recorder.js +152 -0
- package/dist/relation-write.d.ts +41 -0
- package/dist/relation-write.d.ts.map +1 -0
- package/dist/relation-write.js +112 -0
- package/dist/relations.d.ts +42 -0
- package/dist/relations.d.ts.map +1 -0
- package/dist/relations.js +119 -0
- package/dist/rules.d.ts +97 -0
- package/dist/rules.d.ts.map +1 -0
- package/dist/rules.js +71 -0
- package/dist/running.d.ts +29 -0
- package/dist/running.d.ts.map +1 -0
- package/dist/running.js +39 -0
- package/dist/schema-indexes.d.ts +11 -0
- package/dist/schema-indexes.d.ts.map +1 -0
- package/dist/schema-indexes.js +59 -0
- package/dist/schema-virtuals.d.ts +19 -0
- package/dist/schema-virtuals.d.ts.map +1 -0
- package/dist/schema-virtuals.js +100 -0
- package/dist/schema.d.ts +35 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +267 -0
- package/dist/scope.d.ts +46 -0
- package/dist/scope.d.ts.map +1 -0
- package/dist/scope.js +82 -0
- package/dist/scratch.d.ts +14 -0
- package/dist/scratch.d.ts.map +1 -0
- package/dist/scratch.js +10 -0
- package/dist/serve.d.ts +2 -0
- package/dist/serve.d.ts.map +1 -0
- package/dist/serve.js +4 -0
- package/dist/symbols.d.ts +10 -0
- package/dist/symbols.d.ts.map +1 -0
- package/dist/symbols.js +1 -0
- package/dist/transaction.d.ts +28 -0
- package/dist/transaction.d.ts.map +1 -0
- package/dist/transaction.js +156 -0
- package/dist/types.d.ts +58 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/update-many.d.ts +7 -0
- package/dist/update-many.d.ts.map +1 -0
- package/dist/update-many.js +182 -0
- package/dist/uuid.d.ts +7 -0
- package/dist/uuid.d.ts.map +1 -0
- package/dist/uuid.js +48 -0
- package/dist/validation.d.ts +24 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +72 -0
- package/dist/virtual-read.d.ts +9 -0
- package/dist/virtual-read.d.ts.map +1 -0
- package/dist/virtual-read.js +145 -0
- package/dist/virtual.d.ts +142 -0
- package/dist/virtual.d.ts.map +1 -0
- package/dist/virtual.js +1 -0
- package/dist/write-context.d.ts +46 -0
- package/dist/write-context.d.ts.map +1 -0
- package/dist/write-context.js +102 -0
- package/dist/write-data.d.ts +26 -0
- package/dist/write-data.d.ts.map +1 -0
- package/dist/write-data.js +144 -0
- package/dist/write-plan.d.ts +107 -0
- package/dist/write-plan.d.ts.map +1 -0
- package/dist/write-plan.js +170 -0
- package/dist/write-target.d.ts +17 -0
- package/dist/write-target.d.ts.map +1 -0
- package/dist/write-target.js +59 -0
- package/dist/writes.d.ts +23 -0
- package/dist/writes.d.ts.map +1 -0
- package/dist/writes.js +246 -0
- package/dist/writing.d.ts +10 -0
- package/dist/writing.d.ts.map +1 -0
- package/dist/writing.js +66 -0
- package/package.json +42 -3
- package/src/access.ts +329 -0
- package/src/adapter-errors.ts +89 -0
- package/src/adapter-json.ts +21 -0
- package/src/adapter-migrations.ts +98 -0
- package/src/adapter.ts +363 -0
- package/src/aggregate.ts +136 -0
- package/src/app-internals.ts +26 -0
- package/src/app-options.ts +24 -0
- package/src/cascade.ts +297 -0
- package/src/cli-config.ts +45 -0
- package/src/cli-deploy.ts +235 -0
- package/src/cli-main.ts +165 -0
- package/src/cli-migrate.ts +143 -0
- package/src/cli.ts +5 -0
- package/src/complete.ts +73 -0
- package/src/console-logger.ts +87 -0
- package/src/create-many.ts +126 -0
- package/src/decimal.ts +74 -0
- package/src/define-app.ts +108 -0
- package/src/define-enum.ts +26 -0
- package/src/define-function.ts +188 -0
- package/src/define-model.ts +220 -0
- package/src/definition.ts +352 -0
- package/src/delete-many.ts +76 -0
- package/src/engine.ts +281 -0
- package/src/errors.ts +97 -0
- package/src/exact.ts +49 -0
- package/src/feed.ts +39 -0
- package/src/field-codec.ts +72 -0
- package/src/field-rules.ts +77 -0
- package/src/field-type.ts +219 -0
- package/src/fields.ts +383 -0
- package/src/function.ts +143 -0
- package/src/functions.ts +154 -0
- package/src/group-by.ts +186 -0
- package/src/group-having.ts +143 -0
- package/src/hooks.ts +215 -0
- package/src/hosts.ts +11 -0
- package/src/identify.ts +95 -0
- package/src/index.ts +125 -0
- package/src/internal.ts +68 -0
- package/src/lifecycle.ts +214 -0
- package/src/list-update.ts +71 -0
- package/src/live.ts +199 -0
- package/src/manifest.ts +71 -0
- package/src/memory-aggregate.ts +162 -0
- package/src/memory-conditions.ts +88 -0
- package/src/memory-draft.ts +319 -0
- package/src/memory-json.ts +91 -0
- package/src/memory-read.ts +311 -0
- package/src/memory-search.ts +149 -0
- package/src/memory-values.ts +106 -0
- package/src/memory.ts +173 -0
- package/src/migrate.ts +152 -0
- package/src/model.ts +312 -0
- package/src/nested-write.ts +390 -0
- package/src/number-update.ts +142 -0
- package/src/plugin-app.ts +308 -0
- package/src/plugin-code.ts +158 -0
- package/src/plugin-use.ts +217 -0
- package/src/plugin.ts +400 -0
- package/src/query-aggregate.ts +96 -0
- package/src/query-args.ts +375 -0
- package/src/query-bulk.ts +53 -0
- package/src/query-conditions.ts +53 -0
- package/src/query-context.ts +104 -0
- package/src/query-filter.ts +54 -0
- package/src/query-group.ts +137 -0
- package/src/query-json.ts +90 -0
- package/src/query-order.ts +158 -0
- package/src/query-project.ts +73 -0
- package/src/query-search.ts +31 -0
- package/src/query-values.ts +131 -0
- package/src/query-where.ts +318 -0
- package/src/query-write.ts +360 -0
- package/src/query.ts +400 -0
- package/src/record.ts +379 -0
- package/src/recorder.ts +212 -0
- package/src/relation-write.ts +176 -0
- package/src/relations.ts +165 -0
- package/src/rules.ts +188 -0
- package/src/running.ts +62 -0
- package/src/schema-indexes.ts +88 -0
- package/src/schema-virtuals.ts +134 -0
- package/src/schema.ts +367 -0
- package/src/scope.ts +123 -0
- package/src/scratch.ts +28 -0
- package/src/serve.ts +5 -0
- package/src/symbols.ts +11 -0
- package/src/transaction.ts +211 -0
- package/src/types.ts +79 -0
- package/src/update-many.ts +268 -0
- package/src/uuid.ts +51 -0
- package/src/validation.ts +107 -0
- package/src/virtual-read.ts +198 -0
- package/src/virtual.ts +187 -0
- package/src/write-context.ts +170 -0
- package/src/write-data.ts +188 -0
- package/src/write-plan.ts +273 -0
- package/src/write-target.ts +92 -0
- package/src/writes.ts +361 -0
- package/src/writing.ts +93 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Issue } from './errors.ts';
|
|
2
|
+
import type { StandardSchema } from './fields.ts';
|
|
3
|
+
import type { FieldInfo, ModelInfo } from './schema.ts';
|
|
4
|
+
export type Result = {
|
|
5
|
+
readonly value: unknown;
|
|
6
|
+
} | {
|
|
7
|
+
readonly issues: readonly Issue[];
|
|
8
|
+
};
|
|
9
|
+
/** A Standard Schema, its `~standard` and that object's `validate`. */
|
|
10
|
+
export type Standard = {
|
|
11
|
+
readonly schema: StandardSchema;
|
|
12
|
+
readonly self: object;
|
|
13
|
+
readonly validate: Function;
|
|
14
|
+
};
|
|
15
|
+
/** A Standard Schema's `~standard`, or `undefined` for any other value. */
|
|
16
|
+
export declare function standardOf(schema: unknown): Standard | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* What a Standard Schema returns for `value`, its issues' paths behind
|
|
19
|
+
* `prefix`; `where` names the schema when it breaks the standard.
|
|
20
|
+
*/
|
|
21
|
+
export declare function checked(standard: Standard, value: unknown, prefix: readonly (string | number)[], where: string): Promise<Result>;
|
|
22
|
+
/** The value to store, or the issues that refuse it. */
|
|
23
|
+
export declare function validated(model: ModelInfo, field: FieldInfo, value: unknown): Promise<Result>;
|
|
24
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAGvD,MAAM,MAAM,MAAM,GACjB;IAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAA;CAAE,CAAA;AAEpE,uEAAuE;AACvE,MAAM,MAAM,QAAQ,GAAG;IACtB,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAA;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;CAC3B,CAAA;AAED,2EAA2E;AAC3E,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAYhE;AAmBD;;;GAGG;AACH,wBAAsB,OAAO,CAC5B,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACpC,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,CAqBjB;AAED,wDAAwD;AACxD,wBAAsB,SAAS,CAC9B,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,OAAO,GACZ,OAAO,CAAC,MAAM,CAAC,CAoBjB"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { isObject } from './query-where.js';
|
|
2
|
+
/** A Standard Schema's `~standard`, or `undefined` for any other value. */
|
|
3
|
+
export function standardOf(schema) {
|
|
4
|
+
if (typeof schema !== 'object' && typeof schema !== 'function') {
|
|
5
|
+
return undefined;
|
|
6
|
+
}
|
|
7
|
+
if (schema === null)
|
|
8
|
+
return undefined;
|
|
9
|
+
const standard = Reflect.get(schema, '~standard');
|
|
10
|
+
if (!isObject(standard) || typeof standard['validate'] !== 'function') {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- a `~standard` with a `validate` is the interface; each result is checked.
|
|
14
|
+
const typed = schema;
|
|
15
|
+
return { schema: typed, self: standard, validate: standard['validate'] };
|
|
16
|
+
}
|
|
17
|
+
/** A schema issue's path, behind `prefix`. */
|
|
18
|
+
function pathOf(prefix, path) {
|
|
19
|
+
if (!Array.isArray(path))
|
|
20
|
+
return [...prefix];
|
|
21
|
+
return [
|
|
22
|
+
...prefix,
|
|
23
|
+
...path.map((segment) => {
|
|
24
|
+
const key = isObject(segment) ? segment['key'] : segment;
|
|
25
|
+
return typeof key === 'string' || typeof key === 'number'
|
|
26
|
+
? key
|
|
27
|
+
: String(key);
|
|
28
|
+
}),
|
|
29
|
+
];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* What a Standard Schema returns for `value`, its issues' paths behind
|
|
33
|
+
* `prefix`; `where` names the schema when it breaks the standard.
|
|
34
|
+
*/
|
|
35
|
+
export async function checked(standard, value, prefix, where) {
|
|
36
|
+
const result = await Reflect.apply(standard.validate, standard.self, [value]);
|
|
37
|
+
if (isObject(result) && Array.isArray(result['issues'])) {
|
|
38
|
+
return {
|
|
39
|
+
issues: result['issues'].map((issue) => ({
|
|
40
|
+
path: pathOf(prefix, isObject(issue) ? issue['path'] : undefined),
|
|
41
|
+
message: isObject(issue) && typeof issue['message'] === 'string'
|
|
42
|
+
? issue['message']
|
|
43
|
+
: 'Invalid value.',
|
|
44
|
+
})),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
if (isObject(result) && 'value' in result)
|
|
48
|
+
return { value: result['value'] };
|
|
49
|
+
throw new TypeError(`${where}: the schema returned no Standard Schema result.`);
|
|
50
|
+
}
|
|
51
|
+
/** The value to store, or the issues that refuse it. */
|
|
52
|
+
export async function validated(model, field, value) {
|
|
53
|
+
const validate = field.options['validate'];
|
|
54
|
+
if (validate === undefined)
|
|
55
|
+
return { value };
|
|
56
|
+
const standard = standardOf(validate);
|
|
57
|
+
if (standard !== undefined) {
|
|
58
|
+
return checked(standard, value, [field.name], `${model.name}.${field.name}`);
|
|
59
|
+
}
|
|
60
|
+
if (typeof validate !== 'function') {
|
|
61
|
+
throw new TypeError(`${model.name}.${field.name}: validate is a Standard Schema or a function.`);
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
const output = await Reflect.apply(validate, undefined, [value]);
|
|
65
|
+
return { value: output };
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
// The function refuses by throwing; its message is for the client (D-88).
|
|
69
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
70
|
+
return { issues: [{ path: [field.name], message }] };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Shape } from './query-args.ts';
|
|
2
|
+
import type { Context } from './query-context.ts';
|
|
3
|
+
import type { Computed, Hidden } from './query-project.ts';
|
|
4
|
+
import type { Store } from './transaction.ts';
|
|
5
|
+
/** Counts a query toward the `run` calls that send it. */
|
|
6
|
+
export declare function counted(): void;
|
|
7
|
+
/** The virtuals of `rows` and of their relations' rows, by row. */
|
|
8
|
+
export declare function computeVirtuals(context: Context, store: Store, rows: readonly unknown[], shape: Shape, hidden: Hidden | undefined, computed?: Computed): Promise<Computed>;
|
|
9
|
+
//# sourceMappingURL=virtual-read.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virtual-read.d.ts","sourceRoot":"","sources":["../src/virtual-read.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAe,MAAM,iBAAiB,CAAA;AAEzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAI1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAS7C,0DAA0D;AAC1D,wBAAgB,OAAO,IAAI,IAAI,CAG9B;AASD,mEAAmE;AACnE,wBAAsB,eAAe,CACpC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,SAAS,OAAO,EAAE,EACxB,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,QAAQ,GAAE,QAAwB,GAChC,OAAO,CAAC,QAAQ,CAAC,CAuBnB"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// Virtual fields on read (D-151): each one's input validated once per node
|
|
2
|
+
// of the shape, its `run` or `runMany` called as the caller for the rows
|
|
3
|
+
// that show it, and a model's rows re-read by id for their relations.
|
|
4
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
5
|
+
import { PublicError } from './errors.js';
|
|
6
|
+
import { restrict } from './query-args.js';
|
|
7
|
+
import { project, unseenVirtuals } from './query-project.js';
|
|
8
|
+
import { isObject, normalizeWhere } from './query-where.js';
|
|
9
|
+
import { planned } from './scope.js';
|
|
10
|
+
import { checked } from './validation.js';
|
|
11
|
+
/** The queries the `run` calls of one virtual send, for the N+1 warning. */
|
|
12
|
+
const sent = new AsyncLocalStorage();
|
|
13
|
+
const warned = new WeakSet();
|
|
14
|
+
/** Counts a query toward the `run` calls that send it. */
|
|
15
|
+
export function counted() {
|
|
16
|
+
const calls = sent.getStore();
|
|
17
|
+
if (calls !== undefined)
|
|
18
|
+
calls.count += 1;
|
|
19
|
+
}
|
|
20
|
+
const rowsOf = (value) => (Array.isArray(value) ? value : [value]).filter(isObject);
|
|
21
|
+
/** Whether a virtual is computed at or below `shape`. */
|
|
22
|
+
const computes = (shape) => shape.virtuals.size > 0 || [...shape.relations.values()].some(computes);
|
|
23
|
+
/** The virtuals of `rows` and of their relations' rows, by row. */
|
|
24
|
+
export async function computeVirtuals(context, store, rows, shape, hidden, computed = new WeakMap()) {
|
|
25
|
+
if (!computes(shape))
|
|
26
|
+
return computed;
|
|
27
|
+
const found = rows.flatMap(rowsOf);
|
|
28
|
+
for (const [name, nested] of shape.relations) {
|
|
29
|
+
const below = found.flatMap((row) => rowsOf(row[name]));
|
|
30
|
+
await computeVirtuals(context, store, below, nested, hidden, computed);
|
|
31
|
+
}
|
|
32
|
+
if (shape.virtuals.size === 0)
|
|
33
|
+
return computed;
|
|
34
|
+
const unseen = new Map(found.map((row) => [row, unseenVirtuals(shape, row, hidden)]));
|
|
35
|
+
for (const read of shape.virtuals.values()) {
|
|
36
|
+
const { name } = read.info;
|
|
37
|
+
const shown = found.filter((row) => unseen.get(row)?.has(name) !== true);
|
|
38
|
+
if (shown.length === 0)
|
|
39
|
+
continue;
|
|
40
|
+
const values = await valuesOf(context, store, read, shown, hidden);
|
|
41
|
+
shown.forEach((row, index) => {
|
|
42
|
+
const known = computed.get(row) ?? new Map();
|
|
43
|
+
known.set(name, values[index]);
|
|
44
|
+
computed.set(row, known);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return computed;
|
|
48
|
+
}
|
|
49
|
+
/** The value of `read` for each row, in order. */
|
|
50
|
+
async function valuesOf(context, store, read, rows, hidden) {
|
|
51
|
+
const { info, path } = read;
|
|
52
|
+
const where = `${info.model}.${info.name}`;
|
|
53
|
+
let input;
|
|
54
|
+
if (info.input !== undefined) {
|
|
55
|
+
const prefix = path === '' ? [] : path.split('.');
|
|
56
|
+
const result = await checked(info.input, read.input, prefix, where);
|
|
57
|
+
if ('issues' in result) {
|
|
58
|
+
throw new PublicError('VALIDATION_FAILED', 'Invalid input.', {
|
|
59
|
+
details: { issues: result.issues },
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
input = result.value;
|
|
63
|
+
}
|
|
64
|
+
const { caller } = context;
|
|
65
|
+
const records = rows.map((row) => Object.freeze(Object.fromEntries(info.needs.map((need) => [need, row[need] ?? null]))));
|
|
66
|
+
let values;
|
|
67
|
+
if (info.many) {
|
|
68
|
+
// Its queries are its own, not those of a `run` around it.
|
|
69
|
+
const result = await sent.exit(async () => info.run(Object.freeze({ caller, input, records })));
|
|
70
|
+
if (!Array.isArray(result) || result.length !== records.length) {
|
|
71
|
+
throw new TypeError(`${where}: runMany returns one value per record, ${records.length} here.`);
|
|
72
|
+
}
|
|
73
|
+
values = result;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const calls = { count: 0 };
|
|
77
|
+
values = await sent.run(calls, async () => Promise.all(records.map(async (record) => info.run(Object.freeze({ caller, input, record })))));
|
|
78
|
+
perRow(context, read, records.length, calls.count);
|
|
79
|
+
}
|
|
80
|
+
return info.output.kind === 'model'
|
|
81
|
+
? rereadRows(context, store, read, values, hidden)
|
|
82
|
+
: values;
|
|
83
|
+
}
|
|
84
|
+
/** Warns once per field, outside production, of a `run` querying per row. */
|
|
85
|
+
function perRow(context, read, rows, queries) {
|
|
86
|
+
const { info } = read;
|
|
87
|
+
if (rows < 2 || queries < rows || warned.has(info))
|
|
88
|
+
return;
|
|
89
|
+
if (process.env['NODE_ENV'] === 'production')
|
|
90
|
+
return;
|
|
91
|
+
warned.add(info);
|
|
92
|
+
context.app.logger.warn({ model: info.model, field: info.name }, `${info.model}.${info.name}: run queried the database once per row; use runMany.`);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* The rows `run` returned, shaped: their scalars as returned, their
|
|
96
|
+
* relations and counts re-read by id as the caller, in one query.
|
|
97
|
+
*/
|
|
98
|
+
async function rereadRows(context, store, read, values, hidden) {
|
|
99
|
+
const { info, plan } = read;
|
|
100
|
+
const { output } = info;
|
|
101
|
+
if (plan === undefined || output.kind !== 'model')
|
|
102
|
+
return values;
|
|
103
|
+
const list = output.form === 'list';
|
|
104
|
+
const items = values.flatMap(rowsOf);
|
|
105
|
+
for (const item of items) {
|
|
106
|
+
if (typeof item['id'] !== 'string') {
|
|
107
|
+
throw new TypeError(`${info.model}.${info.name} returned a ${output.name} without its id.`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const { shape } = plan;
|
|
111
|
+
const target = shape.model;
|
|
112
|
+
const found = new Map();
|
|
113
|
+
if (shape.relations.size > 0 || shape.counts.length > 0) {
|
|
114
|
+
const { models, scope } = context;
|
|
115
|
+
const ids = [...new Set(items.map((item) => item['id']))];
|
|
116
|
+
const readable = await planned(scope, () => scope.readable(target.name));
|
|
117
|
+
const byIds = normalizeWhere(models, target, { id: { in: ids } }, 'where');
|
|
118
|
+
const rows = await store.find({
|
|
119
|
+
model: target.name,
|
|
120
|
+
...restrict({ ...plan.read, where: byIds }, readable),
|
|
121
|
+
});
|
|
122
|
+
for (const row of rows)
|
|
123
|
+
found.set(row['id'], row);
|
|
124
|
+
}
|
|
125
|
+
const copies = new Map();
|
|
126
|
+
for (const item of items) {
|
|
127
|
+
const row = found.get(item['id']);
|
|
128
|
+
const copy = { ...item };
|
|
129
|
+
// A row the caller cannot read has no relations (D-109).
|
|
130
|
+
for (const name of shape.relations.keys()) {
|
|
131
|
+
const empty = target.fields.get(name)?.kind === 'many' ? [] : null;
|
|
132
|
+
copy[name] = row === undefined ? empty : row[name];
|
|
133
|
+
}
|
|
134
|
+
if (shape.counts.length > 0)
|
|
135
|
+
copy['_count'] = row?.['_count'];
|
|
136
|
+
copies.set(item, copy);
|
|
137
|
+
}
|
|
138
|
+
const below = [...copies.values()];
|
|
139
|
+
const computed = await computeVirtuals(context, store, below, shape, hidden);
|
|
140
|
+
const shaped = (item) => {
|
|
141
|
+
const copy = isObject(item) ? copies.get(item) : undefined;
|
|
142
|
+
return copy === undefined ? null : project(copy, shape, hidden, computed);
|
|
143
|
+
};
|
|
144
|
+
return values.map((value) => list && Array.isArray(value) ? value.map(shaped) : shaped(value));
|
|
145
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import type { SchemaTypes, StandardSchema } from './fields.ts';
|
|
2
|
+
import type { OutputValue } from './function.ts';
|
|
3
|
+
import type { Payload, Shaping } from './query.ts';
|
|
4
|
+
import type { RecordFor, RecordOf } from './record.ts';
|
|
5
|
+
import type { Caller } from './rules.ts';
|
|
6
|
+
import type { fieldType, modelFields, nullableOf } from './symbols.ts';
|
|
7
|
+
/** A virtual's arguments, the fields `run` reads and what it means. */
|
|
8
|
+
export type VirtualOptions = {
|
|
9
|
+
/** A Standard Schema of an object: the field's arguments, flat. */
|
|
10
|
+
readonly input?: StandardSchema;
|
|
11
|
+
/** The scalar fields `run` reads, which the kernel always reads. */
|
|
12
|
+
readonly needs?: readonly string[];
|
|
13
|
+
readonly description?: string;
|
|
14
|
+
};
|
|
15
|
+
/** The options of a virtual given none. */
|
|
16
|
+
export type NoOptions = {
|
|
17
|
+
readonly input?: never;
|
|
18
|
+
readonly needs?: never;
|
|
19
|
+
};
|
|
20
|
+
type ReadRule = (facts: {
|
|
21
|
+
readonly caller: Caller;
|
|
22
|
+
readonly operation: 'read';
|
|
23
|
+
readonly record: RecordFor<never>;
|
|
24
|
+
}) => boolean;
|
|
25
|
+
/** A virtual's `.with`: a read rule, which hides it further (D-44). */
|
|
26
|
+
export type VirtualWith = {
|
|
27
|
+
readonly access?: ReadRule | {
|
|
28
|
+
readonly read?: ReadRule;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
export interface Virtual<O, X> {
|
|
32
|
+
readonly [fieldType]: {
|
|
33
|
+
readonly kind: 'virtual';
|
|
34
|
+
readonly output: O;
|
|
35
|
+
readonly options: X;
|
|
36
|
+
};
|
|
37
|
+
with(rules: VirtualWith): Virtual<O, X>;
|
|
38
|
+
}
|
|
39
|
+
/** The output a virtual's thunk returns, `[X]` for a list, or its schema. */
|
|
40
|
+
type OutputOf<O> = O extends StandardSchema ? O : O extends () => infer R ? R extends readonly [unknown] ? R : R extends readonly (infer X)[] ? readonly [X] : R : never;
|
|
41
|
+
/** What `run` returns for one row: a model's scalars, a type, a value. */
|
|
42
|
+
export type VirtualValue<O> = OutputValue<OutputOf<O>>;
|
|
43
|
+
type Facts<X> = X extends {
|
|
44
|
+
readonly [fieldType]: {
|
|
45
|
+
readonly output: infer O;
|
|
46
|
+
readonly options: infer P;
|
|
47
|
+
};
|
|
48
|
+
} ? {
|
|
49
|
+
readonly output: O;
|
|
50
|
+
readonly options: P;
|
|
51
|
+
} : never;
|
|
52
|
+
type In<P> = P extends {
|
|
53
|
+
readonly input: infer S;
|
|
54
|
+
} ? SchemaTypes<S> extends {
|
|
55
|
+
readonly output: infer O;
|
|
56
|
+
} ? O : never : undefined;
|
|
57
|
+
type NeedsOf<P> = P extends {
|
|
58
|
+
readonly needs: readonly (infer K)[];
|
|
59
|
+
} ? K : never;
|
|
60
|
+
type Row<F, P> = Pick<RecordOf<F>, (NeedsOf<P> & keyof RecordOf<F>) | 'id'>;
|
|
61
|
+
export type VirtualKeys<F> = {
|
|
62
|
+
[K in keyof F]: F[K] extends {
|
|
63
|
+
readonly [fieldType]: {
|
|
64
|
+
readonly kind: 'virtual';
|
|
65
|
+
};
|
|
66
|
+
} ? K : never;
|
|
67
|
+
}[keyof F];
|
|
68
|
+
type Rule<F, O, P> = {
|
|
69
|
+
readonly run: (facts: {
|
|
70
|
+
readonly caller: Caller;
|
|
71
|
+
readonly input: In<P>;
|
|
72
|
+
readonly record: Row<F, P>;
|
|
73
|
+
}) => VirtualValue<O> | Promise<VirtualValue<O>>;
|
|
74
|
+
readonly runMany?: never;
|
|
75
|
+
} | {
|
|
76
|
+
/** One value per record, in their order. */
|
|
77
|
+
readonly runMany: (facts: {
|
|
78
|
+
readonly caller: Caller;
|
|
79
|
+
readonly input: In<P>;
|
|
80
|
+
readonly records: readonly Row<F, P>[];
|
|
81
|
+
}) => readonly VirtualValue<O>[] | Promise<readonly VirtualValue<O>[]>;
|
|
82
|
+
readonly run?: never;
|
|
83
|
+
};
|
|
84
|
+
/** A `needs` that names no field of the model fails to compile. */
|
|
85
|
+
type Checked<F, X> = Facts<X> extends {
|
|
86
|
+
readonly output: infer O;
|
|
87
|
+
readonly options: infer P;
|
|
88
|
+
} ? [Exclude<NeedsOf<P>, keyof RecordOf<F>>] extends [never] ? Rule<F, O, P> : {
|
|
89
|
+
readonly unknownNeeds: Exclude<NeedsOf<P>, keyof RecordOf<F>>;
|
|
90
|
+
} : never;
|
|
91
|
+
/** `run` or `runMany` for each virtual of the model. */
|
|
92
|
+
export type VirtualRules<F> = {
|
|
93
|
+
readonly [K in VirtualKeys<F>]: Checked<F, F[K]>;
|
|
94
|
+
};
|
|
95
|
+
/** The model a virtual returns rows of, `never` for another output. */
|
|
96
|
+
type ModelOf<R> = R extends {
|
|
97
|
+
readonly [modelFields]: infer F;
|
|
98
|
+
} ? F : R extends {
|
|
99
|
+
readonly [nullableOf]: infer X;
|
|
100
|
+
} ? ModelOf<X> : R extends readonly [infer X] ? ModelOf<X> : never;
|
|
101
|
+
type InputOf<P> = P extends {
|
|
102
|
+
readonly input: infer S;
|
|
103
|
+
} ? SchemaTypes<S> extends {
|
|
104
|
+
readonly input: infer I;
|
|
105
|
+
} ? I : never : never;
|
|
106
|
+
/** Whether a virtual is in the default row: a value without input. */
|
|
107
|
+
type IsDefault<X> = Facts<X> extends {
|
|
108
|
+
readonly output: infer O;
|
|
109
|
+
readonly options: infer P;
|
|
110
|
+
} ? O extends StandardSchema ? [InputOf<P>] extends [never] ? true : false : false : false;
|
|
111
|
+
export type DefaultVirtualKeys<F> = {
|
|
112
|
+
[K in VirtualKeys<F>]: IsDefault<F[K]> extends true ? K : never;
|
|
113
|
+
}[VirtualKeys<F>];
|
|
114
|
+
/**
|
|
115
|
+
* A virtual's `select` or `include`: `true` when its input properties are
|
|
116
|
+
* all optional, else its input, and a model's `select`, `include` and `omit`.
|
|
117
|
+
*/
|
|
118
|
+
export type VirtualArgs<X> = Facts<X> extends {
|
|
119
|
+
readonly output: infer O;
|
|
120
|
+
readonly options: infer P;
|
|
121
|
+
} ? ([InputOf<P>] extends [never] ? boolean : Partial<InputOf<P>> extends InputOf<P> ? boolean : never) | ([InputOf<P> | ModelOf<OutputOf<O>>] extends [never] ? never : ([InputOf<P>] extends [never] ? unknown : InputOf<P>) & ([ModelOf<OutputOf<O>>] extends [never] ? unknown : Shaping<ModelOf<OutputOf<O>>>)) : never;
|
|
122
|
+
type Shaped<R, A> = R extends {
|
|
123
|
+
readonly [modelFields]: infer F;
|
|
124
|
+
} ? Payload<F, A> : R extends {
|
|
125
|
+
readonly [nullableOf]: infer X;
|
|
126
|
+
} ? Shaped<X, A> | null : R extends readonly [infer X] ? Shaped<X, A>[] : OutputValue<R>;
|
|
127
|
+
/** A selected virtual's value, its rows shaped by `A`. */
|
|
128
|
+
export type VirtualOutput<X, A> = Facts<X> extends {
|
|
129
|
+
readonly output: infer O;
|
|
130
|
+
} ? Shaped<OutputOf<O>, A> : never;
|
|
131
|
+
/** The virtuals of the default row. */
|
|
132
|
+
export type DefaultVirtuals<F> = {
|
|
133
|
+
readonly [K in DefaultVirtualKeys<F>]: VirtualOutput<F[K], true>;
|
|
134
|
+
};
|
|
135
|
+
/** A row without `select`: its scalars, and its default virtuals. */
|
|
136
|
+
export type DefaultRow<F> = [DefaultVirtualKeys<F>] extends [never] ? RecordOf<F> : RecordOf<F> & DefaultVirtuals<F>;
|
|
137
|
+
/** The virtuals an `include` takes, none for a model without. */
|
|
138
|
+
export type VirtualIncludes<F> = [VirtualKeys<F>] extends [never] ? unknown : {
|
|
139
|
+
readonly [K in VirtualKeys<F>]?: VirtualArgs<F[K]>;
|
|
140
|
+
};
|
|
141
|
+
export {};
|
|
142
|
+
//# sourceMappingURL=virtual.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virtual.d.ts","sourceRoot":"","sources":["../src/virtual.ts"],"names":[],"mappings":"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"}
|
package/dist/virtual.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Many, Resolving } from './nested-write.ts';
|
|
2
|
+
import type { FieldInfo, ModelInfo } from './schema.ts';
|
|
3
|
+
import type { QueryScope } from './scope.ts';
|
|
4
|
+
import type { Draft } from './write-data.ts';
|
|
5
|
+
import type { Plan, Reads, Step } from './write-plan.ts';
|
|
6
|
+
export type Relation = Extract<FieldInfo, {
|
|
7
|
+
readonly kind: 'one' | 'many';
|
|
8
|
+
}>;
|
|
9
|
+
export type Context = {
|
|
10
|
+
readonly scope: QueryScope;
|
|
11
|
+
readonly model: ModelInfo;
|
|
12
|
+
readonly id: string;
|
|
13
|
+
readonly plan: Plan;
|
|
14
|
+
readonly reads: Reads;
|
|
15
|
+
/** The data the caller sent, before defaults and hooks. */
|
|
16
|
+
readonly sent: Readonly<Draft>;
|
|
17
|
+
readonly set: {
|
|
18
|
+
[field: string]: unknown;
|
|
19
|
+
};
|
|
20
|
+
/** The steps that run before the row's own: the rows it points to. */
|
|
21
|
+
readonly before: Step[];
|
|
22
|
+
/** The steps that run after the row's own. */
|
|
23
|
+
readonly after: Step[];
|
|
24
|
+
/** Where the row's data sits in the write's `data` (D-128). */
|
|
25
|
+
readonly at: readonly (string | number)[];
|
|
26
|
+
};
|
|
27
|
+
export declare function fail(context: Context, path: readonly string[], message: string): void;
|
|
28
|
+
export declare const pathOf: (context: Context, name: string) => string;
|
|
29
|
+
/**
|
|
30
|
+
* A relation value the caller did not send, a default's or a hook's, skips
|
|
31
|
+
* access rules (D-67); `beforeFind` still applies (D-71).
|
|
32
|
+
*/
|
|
33
|
+
export declare function trusted(context: Context, field: FieldInfo, value: unknown): boolean;
|
|
34
|
+
/** The row's relation values, resolved as the caller or a hook sent them. */
|
|
35
|
+
export declare const resolving: (context: Context, skips: boolean, creating: boolean) => Resolving;
|
|
36
|
+
export declare function scalar(context: Context, field: FieldInfo, value: unknown): void;
|
|
37
|
+
/** Whether a row of the other side, but `kept`, holds this one's key. */
|
|
38
|
+
export declare function holds(context: Context, field: Extract<FieldInfo, {
|
|
39
|
+
readonly kind: 'one';
|
|
40
|
+
}>, kept: string | undefined): Promise<boolean>;
|
|
41
|
+
export declare const viaOf: (context: Context, field: Relation) => string;
|
|
42
|
+
/** A `many` relation's link changes: its disconnects, then its connects. */
|
|
43
|
+
export declare function linking(context: Context, field: Extract<FieldInfo, {
|
|
44
|
+
readonly kind: 'many';
|
|
45
|
+
}>, write: Pick<Many, 'connect' | 'disconnect'>, made: readonly string[], skips: boolean): void;
|
|
46
|
+
//# sourceMappingURL=write-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-context.d.ts","sourceRoot":"","sources":["../src/write-context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAExD,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAE5C,OAAO,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AAGxD,MAAM,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,CAAA;CAAE,CAAC,CAAA;AAE5E,MAAM,MAAM,OAAO,GAAG;IACrB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC9B,QAAQ,CAAC,GAAG,EAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAA;IAC1C,sEAAsE;IACtE,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,CAAA;IACvB,8CAA8C;IAC9C,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,CAAA;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;CACzC,CAAA;AAED,wBAAgB,IAAI,CACnB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,MAAM,GACb,IAAI,CAEN;AAED,eAAO,MAAM,MAAM,YAAa,OAAO,QAAQ,MAAM,KAAG,MAChB,CAAA;AAExC;;;GAGG;AACH,wBAAgB,OAAO,CACtB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,OAAO,GACZ,OAAO,CAKT;AAED,6EAA6E;AAC7E,eAAO,MAAM,SAAS,YACZ,OAAO,SACT,OAAO,YACJ,OAAO,KACf,SAAuD,CAAA;AAE1D,wBAAgB,MAAM,CACrB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,OAAO,GACZ,IAAI,CAoBN;AAED,yEAAyE;AACzE,wBAAsB,KAAK,CAC1B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC,EACnD,IAAI,EAAE,MAAM,GAAG,SAAS,GACtB,OAAO,CAAC,OAAO,CAAC,CASlB;AAED,eAAO,MAAM,KAAK,YAAa,OAAO,SAAS,QAAQ,KAAG,MACpB,CAAA;AAEtC,4EAA4E;AAC5E,wBAAgB,OAAO,CACtB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EACpD,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,GAAG,YAAY,CAAC,EAC3C,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,KAAK,EAAE,OAAO,GACZ,IAAI,CAsDN"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { storedValue } from './decimal.js';
|
|
2
|
+
import { issueOf } from './write-data.js';
|
|
3
|
+
import { byId, byIds, modelOf } from './query-where.js';
|
|
4
|
+
export function fail(context, path, message) {
|
|
5
|
+
context.plan.issues.push({ path: [...context.at, ...path], message });
|
|
6
|
+
}
|
|
7
|
+
export const pathOf = (context, name) => ['data', ...context.at, name].join('.');
|
|
8
|
+
/**
|
|
9
|
+
* A relation value the caller did not send, a default's or a hook's, skips
|
|
10
|
+
* access rules (D-67); `beforeFind` still applies (D-71).
|
|
11
|
+
*/
|
|
12
|
+
export function trusted(context, field, value) {
|
|
13
|
+
return (!Object.hasOwn(context.sent, field.name) ||
|
|
14
|
+
context.sent[field.name] !== value);
|
|
15
|
+
}
|
|
16
|
+
/** The row's relation values, resolved as the caller or a hook sent them. */
|
|
17
|
+
export const resolving = (context, skips, creating) => ({ ...context, trusted: skips, creating });
|
|
18
|
+
export function scalar(context, field, value) {
|
|
19
|
+
if (field.kind !== 'scalar')
|
|
20
|
+
return;
|
|
21
|
+
if (value === null) {
|
|
22
|
+
if (field.optional)
|
|
23
|
+
context.set[field.name] = null;
|
|
24
|
+
else
|
|
25
|
+
fail(context, [field.name], 'Required.');
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const { codec } = field;
|
|
29
|
+
// A plugin field is stored in the form its `encode` gives (D-122).
|
|
30
|
+
const stored = codec === undefined ? value : codec.encode(value);
|
|
31
|
+
const issue = issueOf(stored, field);
|
|
32
|
+
const where = `${context.model.name}.${field.name}`;
|
|
33
|
+
if (issue !== undefined) {
|
|
34
|
+
throw new TypeError(codec === undefined
|
|
35
|
+
? `${where}: ${issue} A before hook or validate wrote it.`
|
|
36
|
+
: `${where}: the ${codec.plugin} field type encoded a value its stored field refuses: ${issue}`);
|
|
37
|
+
}
|
|
38
|
+
context.set[field.name] = storedValue(stored, field);
|
|
39
|
+
}
|
|
40
|
+
/** Whether a row of the other side, but `kept`, holds this one's key. */
|
|
41
|
+
export async function holds(context, field, kept) {
|
|
42
|
+
const count = await context.reads.count({
|
|
43
|
+
model: field.target,
|
|
44
|
+
where: {
|
|
45
|
+
[field.inverse]: { is: byId(context.id) },
|
|
46
|
+
...(kept === undefined ? {} : { id: { not: kept } }),
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
return count > 0;
|
|
50
|
+
}
|
|
51
|
+
export const viaOf = (context, field) => `${context.model.name}.${field.name}`;
|
|
52
|
+
/** A `many` relation's link changes: its disconnects, then its connects. */
|
|
53
|
+
export function linking(context, field, write, made, skips) {
|
|
54
|
+
const { connect, disconnect } = write;
|
|
55
|
+
if (field.join) {
|
|
56
|
+
const link = {
|
|
57
|
+
model: context.model.name,
|
|
58
|
+
field: field.name,
|
|
59
|
+
id: context.id,
|
|
60
|
+
};
|
|
61
|
+
if (disconnect.length > 0) {
|
|
62
|
+
context.after.push({
|
|
63
|
+
kind: 'detach',
|
|
64
|
+
...link,
|
|
65
|
+
targets: disconnect,
|
|
66
|
+
target: field.target,
|
|
67
|
+
trusted: skips,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
const targets = [...connect, ...made];
|
|
71
|
+
if (targets.length > 0) {
|
|
72
|
+
context.after.push({ kind: 'link', ...link, targets });
|
|
73
|
+
}
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const inverse = modelOf(context.scope.models, field.target).fields.get(field.inverse);
|
|
77
|
+
const move = {
|
|
78
|
+
kind: 'move',
|
|
79
|
+
model: field.target,
|
|
80
|
+
field: field.inverse,
|
|
81
|
+
via: viaOf(context, field),
|
|
82
|
+
trusted: skips,
|
|
83
|
+
};
|
|
84
|
+
if (disconnect.length > 0) {
|
|
85
|
+
if (inverse?.kind === 'one' && !inverse.optional) {
|
|
86
|
+
fail(context, [field.name, 'disconnect'], `A ${field.target} cannot be left without its ${field.inverse}.`);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
context.after.push({
|
|
90
|
+
...move,
|
|
91
|
+
where: {
|
|
92
|
+
...byIds(disconnect),
|
|
93
|
+
[field.inverse]: { is: byId(context.id) },
|
|
94
|
+
},
|
|
95
|
+
to: null,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (connect.length > 0) {
|
|
100
|
+
context.after.push({ ...move, where: byIds(connect), to: context.id });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Issue } from './errors.ts';
|
|
2
|
+
import { PublicError } from './errors.ts';
|
|
3
|
+
import type { Caller } from './rules.ts';
|
|
4
|
+
import type { ModelInfo } from './schema.ts';
|
|
5
|
+
import type { Models } from './query-where.ts';
|
|
6
|
+
import type { ScalarCheck } from './query-where.ts';
|
|
7
|
+
/** The data a `before*` hook changes in place (D-71). */
|
|
8
|
+
export type Draft = {
|
|
9
|
+
[field: string]: unknown;
|
|
10
|
+
};
|
|
11
|
+
/** A value's issue; each element of a list fits its type (D-127). */
|
|
12
|
+
export declare function issueOf(value: unknown, field: ScalarCheck): string | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* The caller's data, its shape checked, as a draft the hooks may change: a
|
|
15
|
+
* copy, down to the rows it creates and updates, which never write the
|
|
16
|
+
* relation they are written through (D-128, D-138).
|
|
17
|
+
*/
|
|
18
|
+
export declare function readData(models: Models, model: ModelInfo, data: unknown, creating: boolean, at?: string, inverse?: string): Draft;
|
|
19
|
+
/**
|
|
20
|
+
* Gives a create its defaults, then checks each value's type and runs its
|
|
21
|
+
* `validate`, whose output replaces it: defaults are validated, hook values
|
|
22
|
+
* are not (D-67).
|
|
23
|
+
*/
|
|
24
|
+
export declare function prepared(model: ModelInfo, draft: Draft, caller: Caller, creating: boolean, at?: readonly (string | number)[]): Promise<void>;
|
|
25
|
+
export declare function invalid(issues: readonly Issue[]): PublicError;
|
|
26
|
+
//# sourceMappingURL=write-data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-data.d.ts","sourceRoot":"","sources":["../src/write-data.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAgB,WAAW,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AACxC,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAanD,yDAAyD;AACzD,MAAM,MAAM,KAAK,GAAG;IAAE,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAA;AAEhD,qEAAqE;AACrE,wBAAgB,OAAO,CACtB,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,WAAW,GAChB,MAAM,GAAG,SAAS,CAcpB;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CACvB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,SAAS,EAChB,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,OAAO,EACjB,EAAE,SAAS,EACX,OAAO,CAAC,EAAE,MAAM,GACd,KAAK,CA+DP;AA6BD;;;;GAIG;AACH,wBAAsB,QAAQ,CAC7B,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,OAAO,EACjB,EAAE,GAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAO,GACnC,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,WAAW,CAI7D"}
|