@isaijs/core 0.1.0 → 0.1.3
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/adapters/cache/cloudflare-kv/index.d.ts +1 -1
- package/dist/adapters/database/d1/index.d.ts +1 -1
- package/dist/adapters/database/durable-object/index.d.ts +1 -1
- package/dist/adapters/database/sqlite-node/index.d.ts +1 -1
- package/dist/adapters/mail/gmail/index.d.ts +1 -1
- package/dist/adapters/pdf/cloudflare-browser/index.d.ts +1 -1
- package/dist/adapters/queue/cloudflare/index.d.ts +1 -1
- package/dist/adapters/ratelimit/cloudflare/index.d.ts +1 -1
- package/dist/adapters/ratelimit/memory/index.d.ts +1 -1
- package/dist/adapters/runtime/cloudflare/index.d.ts +1 -1
- package/dist/adapters/runtime/cloudflare/index.js +1 -1
- package/dist/adapters/storage/disk/index.d.ts +1 -1
- package/dist/adapters/storage/memory/index.d.ts +1 -1
- package/dist/adapters/storage/r2/index.d.ts +1 -1
- package/dist/auth/index.d.ts +2 -2
- package/dist/auth/index.js +2 -2
- package/dist/{base64url-DwWPqoOT.js → base64url-C5GTYIL5.js} +23 -9
- package/dist/cli/index.js +18 -15
- package/dist/client/index.d.ts +46 -5
- package/dist/client/index.js +156 -8
- package/dist/{create-auth-Byf1-VJw.js → create-auth-Ci0PaBoX.js} +5 -5
- package/dist/{data-layer-BMviRJaW.d.ts → data-layer-D1BFo3wO.d.ts} +29 -12
- package/dist/{data-layer-BNtz40PV.js → data-layer-_TZtuy-F.js} +19 -11
- package/dist/db/index.d.ts +3 -3
- package/dist/db/index.js +5 -5
- package/dist/{index-BVCrbMav.d.ts → index-CYcklQ1l.d.ts} +21 -7
- package/dist/{index-BKwTOLop.d.ts → index-Ce5p2-EB.d.ts} +2 -2
- package/dist/{index-CBWFoL3s.d.ts → index-DlgVg3D8.d.ts} +38 -26
- package/dist/index.d.ts +2 -2
- package/dist/index.js +152 -56
- package/dist/{issues-Bxq4JExX.d.ts → issues-CKto95IW.d.ts} +3 -1
- package/dist/{make-DKzPd2b_.js → make-DKBn79cH.js} +17 -2
- package/dist/{config-D6PexpSC.js → makers-DeSNM0Nd.js} +13 -39
- package/dist/{migrator-C65RM_K-.js → migrator-BU3_PHk8.js} +102 -10
- package/dist/{policies-yVzFCjxU.js → policies-CKIdBFKt.js} +3 -3
- package/dist/ports/index.d.ts +1 -1
- package/dist/{resource-9fjxJgmz.js → resource-CsYksjKc.js} +42 -15
- package/dist/{tables-C3Uza4qK.js → tables-IrLjsomf.js} +4 -4
- package/dist/testing/index.d.ts +2 -2
- package/dist/testing/index.js +6 -6
- package/dist/{types-BFc_NEx8.d.ts → types-S6zF5IXV.d.ts} +15 -12
- package/dist/validation/index.d.ts +3 -3
- package/dist/validation/index.js +1 -1
- package/dist/{validation-l5JG-PFn.js → validation-Cppmd0RV.js} +23 -7
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { a as DatabaseDriver, o as DialectName } from "./index-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { a as DatabaseDriver, o as DialectName } from "./index-Ce5p2-EB.js";
|
|
2
|
+
import { t as Issue } from "./issues-CKto95IW.js";
|
|
3
|
+
import { M as IdInput, Y as StoredFile } from "./index-CYcklQ1l.js";
|
|
4
|
+
import { A as Dialect, G as Model, H as Columns, I as Clock, K as ModelSpec, M as RetiredSnapshot, N as SchemaSnapshot, U as ComputedFields, V as AnyModel, W as Fields, X as Condition, at as count, b as RowOf, dt as Kinds, et as Now, f as seed, ft as SchemaDefaults, ht as Field, i as Row, it as any, mt as AnyField, n as Patch, ot as not, p as Database, q as ModelRegistry, rt as all, yt as Slot } from "./types-S6zF5IXV.js";
|
|
4
5
|
//#region src/db/schema/traits.d.ts
|
|
5
6
|
type ComputedDefinitions = Record<string, (row: any) => Condition>;
|
|
6
7
|
interface TraitSpec {
|
|
@@ -79,12 +80,20 @@ declare class CheckFailed extends DatabaseError {
|
|
|
79
80
|
readonly name = "CheckFailed";
|
|
80
81
|
constructor(model: string, check: string, options?: ErrorOptions);
|
|
81
82
|
}
|
|
82
|
-
/**
|
|
83
|
+
/**
|
|
84
|
+
* A unique field (or combination) already has this value. `fields` are the unique's own; `issues`
|
|
85
|
+
* put one on each for a form, except that a field made from another (a slug from its title) puts
|
|
86
|
+
* it on that one, the field a person typed.
|
|
87
|
+
*/
|
|
83
88
|
declare class UniqueFailed extends DatabaseError {
|
|
84
89
|
readonly model: string;
|
|
85
90
|
readonly fields: readonly string[];
|
|
86
91
|
readonly name = "UniqueFailed";
|
|
87
|
-
|
|
92
|
+
readonly issues: readonly Issue[];
|
|
93
|
+
constructor(model: string, fields: readonly string[], options?: ErrorOptions & {
|
|
94
|
+
/** The field each generated one is made from: `{ slug: "title" }`. */
|
|
95
|
+
readonly from?: Readonly<Record<string, string>>;
|
|
96
|
+
});
|
|
88
97
|
}
|
|
89
98
|
/** A ref points at a row that doesn't exist, or a delete is restricted by rows that reference it. */
|
|
90
99
|
declare class ReferenceFailed extends DatabaseError {
|
|
@@ -268,7 +277,7 @@ declare class UnsafeMigration extends Error {
|
|
|
268
277
|
//#region src/db/migrations/errors.d.ts
|
|
269
278
|
/**
|
|
270
279
|
* The migrator's errors: one type with a code, a message and a hint, so the CLI prints the same
|
|
271
|
-
* shape for each and picks its exit code from the code
|
|
280
|
+
* shape for each and picks its exit code from the code.
|
|
272
281
|
*/
|
|
273
282
|
type MigrationErrorCode = "migrations.conflict" | "migrations.tampered" | "database.ahead" | "cleanup.notLive" | "migrations.todo" | "migrations.missing" | "migrations.question" | "migrations.rename" | "migrations.uniqueFill" | "data.loops" | "lock.held" | "deploy.held" | "rollback.unknownRelease" | "rollback.beyondCleanup";
|
|
274
283
|
declare class MigrationError extends Error {
|
|
@@ -708,7 +717,7 @@ declare function authTables(f: Kinds, options: AuthTablesOptions): TableSet<{
|
|
|
708
717
|
};
|
|
709
718
|
}>;
|
|
710
719
|
/**
|
|
711
|
-
* Held by the platform
|
|
720
|
+
* Held by the platform: the tenant's people, the owner
|
|
712
721
|
* included, can't take it away or suspend its holder.
|
|
713
722
|
*/
|
|
714
723
|
held: Field<"platform", "platform", true, false, {}>;
|
|
@@ -911,6 +920,11 @@ declare function tenancyTables(f: Kinds, options: TenancyOptions): TableSet<{
|
|
|
911
920
|
//#region src/db/schema/data-layer.d.ts
|
|
912
921
|
/** A project kind: a preset field (`base.line().max(120)`), or a factory for parameterized kinds. */
|
|
913
922
|
type ProjectKind = AnyField | ((...args: any[]) => AnyField);
|
|
923
|
+
/** What a model may say before its traits and fields. */
|
|
924
|
+
interface ModelOptions {
|
|
925
|
+
/** It lives in the platform's database (with tenancy), as its folder does: `db/schema/platform/`. */
|
|
926
|
+
readonly database: "platform";
|
|
927
|
+
}
|
|
914
928
|
interface DataLayerDefinition<P extends Record<string, ProjectKind>, U extends readonly AnyTableSet[]> {
|
|
915
929
|
/**
|
|
916
930
|
* Built-in tables to switch on (`[base.authTables({ database: "tenant" }), base.tenancy({ database: "platform" })]`):
|
|
@@ -922,20 +936,23 @@ interface DataLayerDefinition<P extends Record<string, ProjectKind>, U extends r
|
|
|
922
936
|
}
|
|
923
937
|
/** What `define` gets: the built-in kinds, and the built-in table sets it may `use`. */
|
|
924
938
|
type Base = Kinds & {
|
|
925
|
-
/** User, Session, Account, Verification, Invite, Role and UserRole, in the app's data database
|
|
939
|
+
/** User, Session, Account, Verification, Invite, Role and UserRole, in the app's data database. */
|
|
926
940
|
readonly authTables: (options: AuthTablesOptions) => ReturnType<typeof authTables>;
|
|
927
|
-
/** `Tenant` and `Domain`, in the platform's database
|
|
941
|
+
/** `Tenant` and `Domain`, in the platform's database. */
|
|
928
942
|
readonly tenancy: (options: TenancyOptions) => ReturnType<typeof tenancyTables>;
|
|
929
|
-
/** `Upload` (files uploaded and not yet attached), in the app's data database
|
|
943
|
+
/** `Upload` (files uploaded and not yet attached), in the app's data database. */
|
|
930
944
|
readonly uploads: (options: UploadTablesOptions) => ReturnType<typeof uploadTables>;
|
|
931
|
-
/** `AuditEntry` (the audit log), in the database whose writes it records
|
|
945
|
+
/** `AuditEntry` (the audit log), in the database whose writes it records. */
|
|
932
946
|
readonly audit: (options: AuditTablesOptions) => AuditTables;
|
|
933
947
|
};
|
|
934
948
|
type ProjectKinds<P> = { readonly [K in keyof P]: P[K] extends AnyField ? () => P[K] : P[K]; };
|
|
935
949
|
/** The placeholder for conditions over a model's rows: `const event = row(Event)`. */
|
|
936
950
|
declare function row<M extends AnyModel>(target: M): Columns<M["~fields"], M["name"]>;
|
|
937
951
|
declare function createDataLayer<P extends Record<string, ProjectKind> = {}, const U extends readonly AnyTableSet[] = []>(define?: (base: Base) => DataLayerDefinition<P, U>): {
|
|
938
|
-
model:
|
|
952
|
+
model: {
|
|
953
|
+
<const Name extends string, const T extends readonly AnyTrait[], F extends Fields>(name: Name, ...rest: [...traits: T, fields: F]): Model<Name, TraitFields<T> & F>;
|
|
954
|
+
<const Name extends string, const T extends readonly AnyTrait[], F extends Fields>(name: Name, options: ModelOptions, ...rest: [...traits: T, fields: F]): Model<Name, TraitFields<T> & F>;
|
|
955
|
+
};
|
|
939
956
|
f: Kinds & ProjectKinds<P>;
|
|
940
957
|
builtins: Builtins<U>;
|
|
941
958
|
slots: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
1
|
+
import { F as quantity, k as datetime, m as host, r as isPhoneRegion } from "./validation-Cppmd0RV.js";
|
|
2
|
+
import "./migrator-BU3_PHk8.js";
|
|
3
|
+
import { C as not, M as field, N as fieldKinds, S as count, s as defineModel, u as rowOf, v as all, w as now, y as any } from "./base64url-C5GTYIL5.js";
|
|
4
|
+
import { a as TableSet, i as platformAuthDefinitions, o as defineBuiltins, r as authTables } from "./tables-IrLjsomf.js";
|
|
4
5
|
import { n as seed } from "./seed-BObmdKdP.js";
|
|
5
6
|
//#region src/db/fields/slot.ts
|
|
6
7
|
var Slot = class {
|
|
@@ -89,13 +90,13 @@ function uploadTables(f, options) {
|
|
|
89
90
|
//#endregion
|
|
90
91
|
//#region src/tenancy/tables.ts
|
|
91
92
|
/**
|
|
92
|
-
* The platform's built-in tables
|
|
93
|
+
* The platform's built-in tables, switched on with
|
|
93
94
|
* `use: [base.tenancy({ database: "platform" })]` in `db/index.ts`:
|
|
94
95
|
*
|
|
95
96
|
* Tenant the registry: what the front door finds behind a host, and whether it may answer
|
|
96
97
|
* Domain every host a tenant answers on (its subdomain and custom domains alike)
|
|
97
98
|
* PlatformUser, PlatformSession… the platform's own people (the auth tables, prefixed): who
|
|
98
|
-
* signs in on the platform's host
|
|
99
|
+
* signs in on the platform's host
|
|
99
100
|
*
|
|
100
101
|
* Feature switches are the app's own columns: `builtins.Tenant.extend({ coupons: f.flag() })`.
|
|
101
102
|
*/
|
|
@@ -171,8 +172,10 @@ var ModelRegistry = class {
|
|
|
171
172
|
//#region src/db/schema/traits.ts
|
|
172
173
|
/**
|
|
173
174
|
* Traits: behaviour a model takes whole, written before its fields (`model(name, ...traits,
|
|
174
|
-
* fields)
|
|
175
|
-
*
|
|
175
|
+
* fields)`), Laravel's traits typed. A trait adds fields (so the model's own fields already see
|
|
176
|
+
* them; declaring one of them again is an error), computed fields, and a name the framework reads
|
|
177
|
+
* (`singleton`). Always written `traits.x()`, never imported bare: a bare `publishable()` reads like
|
|
178
|
+
* an action.
|
|
176
179
|
*/
|
|
177
180
|
var Trait = class {
|
|
178
181
|
spec;
|
|
@@ -224,6 +227,8 @@ function builtinTraits() {
|
|
|
224
227
|
* `slots`, `builtins`, the condition language and `seed`. One call serves every database the app
|
|
225
228
|
* has (with isolated tenancy, the tenants' and the platform's).
|
|
226
229
|
*/
|
|
230
|
+
/** A model's options: `{ database: "…" }`, never fields (a field is a kind, not a string). */
|
|
231
|
+
const isOptions = (value) => typeof value === "object" && value !== null && !(value instanceof Trait) && Object.keys(value).length === 1 && typeof value.database === "string";
|
|
227
232
|
/** The placeholder for conditions over a model's rows: `const event = row(Event)`. */
|
|
228
233
|
function row(target) {
|
|
229
234
|
return rowOf(target.spec, target.registry);
|
|
@@ -258,15 +263,18 @@ function createDataLayer(define) {
|
|
|
258
263
|
byDefault
|
|
259
264
|
};
|
|
260
265
|
}
|
|
261
|
-
|
|
262
|
-
const model = (name, ...rest) => {
|
|
266
|
+
function model(name, ...given) {
|
|
263
267
|
if (Object.hasOwn(builtins, name)) throw new TypeError(`isai: ${name} is a built-in table; add columns with builtins.${name}.extend({ … })`);
|
|
268
|
+
const first = given[0];
|
|
269
|
+
const options = given.length > 1 && isOptions(first) ? first : void 0;
|
|
270
|
+
const rest = options ? given.slice(1) : given;
|
|
271
|
+
if (options && options.database !== "platform") throw new TypeError(`isai: model("${name}") takes { database: "platform" } only`);
|
|
264
272
|
const fields = rest.at(-1);
|
|
265
273
|
if (!fields || fields instanceof Trait) throw new TypeError(`isai: model("${name}") needs its fields last`);
|
|
266
274
|
const traits = rest.slice(0, -1);
|
|
267
275
|
if (!traits.every((trait) => trait instanceof Trait)) throw new TypeError(`isai: model("${name}") takes traits, then its fields`);
|
|
268
|
-
return defineModel(registry, name, fields, traits);
|
|
269
|
-
}
|
|
276
|
+
return defineModel(registry, name, fields, traits, { ...options ? { database: options.database } : {} });
|
|
277
|
+
}
|
|
270
278
|
return {
|
|
271
279
|
model,
|
|
272
280
|
f: {
|
package/dist/db/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ValidationError } from "../issues-
|
|
2
|
-
import { $ as Expr, A as Dialect, B as newSecretKey, F as snapshotOf, G as Model, I as Clock, J as Models, K as ModelSpec, L as FixedClock, M as RetiredSnapshot, N as SchemaSnapshot, O as Write, P as emptySnapshot, R as fixedClock, V as AnyModel, X as Condition, Y as Column, _ as database, _t as Storage, a as Visible, at as count, bt as slot, c as Many, d as SeedContext, dt as Kinds, et as Now, ft as SchemaDefaults, g as Transaction, gt as FieldSpec, h as RawValue, ht as Field, i as Row, it as any, j as Rule, k as WriteListener, l as Overrides, lt as ConditionNode, m as DatabaseOptions, n as Patch, nt as Total, o as Make, ot as not, p as Database, pt as fieldKinds, r as Planned, rt as all, st as now, t as Insert, tt as Relation, u as Seed, v as OrderKey, vt as sensitivity, y as Query, yt as Slot, z as systemClock } from "../types-
|
|
3
|
-
import { A as MigrateOptions, B as NotFound, C as MigrationErrorCode, D as Cleanup, E as UnsafeMigration, F as DataStep, H as UniqueFailed, I as TODO, L as dataStep, M as migrate, N as migrateFresh, O as cleanupMigration, P as sync, R as CheckFailed, S as MigrationError, T as UnsafeChange, U as dialectFor, V as ReferenceFailed, W as sqlite, _ as Generated, b as manifest, c as acquireLock, d as setReleaseStatus, f as startRelease, g as makeMigrations, h as makeCleanup, j as Migration, k as Manifest, l as releaseLock, m as checkMigrations, n as row, o as Release, p as applyRules, s as ReleaseStatus, t as createDataLayer, u as rollback, v as generateMigration, w as SuspectedRename, x as structureStep, y as cleanupStep, z as DatabaseError } from "../data-layer-
|
|
1
|
+
import { a as ValidationError } from "../issues-CKto95IW.js";
|
|
2
|
+
import { $ as Expr, A as Dialect, B as newSecretKey, F as snapshotOf, G as Model, I as Clock, J as Models, K as ModelSpec, L as FixedClock, M as RetiredSnapshot, N as SchemaSnapshot, O as Write, P as emptySnapshot, R as fixedClock, V as AnyModel, X as Condition, Y as Column, _ as database, _t as Storage, a as Visible, at as count, bt as slot, c as Many, d as SeedContext, dt as Kinds, et as Now, ft as SchemaDefaults, g as Transaction, gt as FieldSpec, h as RawValue, ht as Field, i as Row, it as any, j as Rule, k as WriteListener, l as Overrides, lt as ConditionNode, m as DatabaseOptions, n as Patch, nt as Total, o as Make, ot as not, p as Database, pt as fieldKinds, r as Planned, rt as all, st as now, t as Insert, tt as Relation, u as Seed, v as OrderKey, vt as sensitivity, y as Query, yt as Slot, z as systemClock } from "../types-S6zF5IXV.js";
|
|
3
|
+
import { A as MigrateOptions, B as NotFound, C as MigrationErrorCode, D as Cleanup, E as UnsafeMigration, F as DataStep, H as UniqueFailed, I as TODO, L as dataStep, M as migrate, N as migrateFresh, O as cleanupMigration, P as sync, R as CheckFailed, S as MigrationError, T as UnsafeChange, U as dialectFor, V as ReferenceFailed, W as sqlite, _ as Generated, b as manifest, c as acquireLock, d as setReleaseStatus, f as startRelease, g as makeMigrations, h as makeCleanup, j as Migration, k as Manifest, l as releaseLock, m as checkMigrations, n as row, o as Release, p as applyRules, s as ReleaseStatus, t as createDataLayer, u as rollback, v as generateMigration, w as SuspectedRename, x as structureStep, y as cleanupStep, z as DatabaseError } from "../data-layer-D1BFo3wO.js";
|
|
4
4
|
export { type AnyModel, CheckFailed, type Cleanup, type Clock, Column, Condition, type ConditionNode, type DataStep, Database, DatabaseError, type DatabaseOptions, type Dialect, Expr, Field, type FieldSpec, type FixedClock, type Generated, type Insert, type Kinds, type Make, type Manifest, type Many, type MigrateOptions, type Migration, MigrationError, type MigrationErrorCode, Model, type ModelSpec, type Models, NotFound, Now, type OrderKey, type Overrides, type Patch, type Planned, Query, type RawValue, ReferenceFailed, Relation, type Release, type ReleaseStatus, type RetiredSnapshot, type Row, type Rule, type SchemaDefaults, type SchemaSnapshot, Seed, type SeedContext, Slot, type Storage, type SuspectedRename, TODO, Total, Transaction, UniqueFailed, type UnsafeChange, UnsafeMigration, ValidationError, type Visible, type Write, type WriteListener, acquireLock, all, any, applyRules, checkMigrations, cleanupMigration, cleanupStep, count, createDataLayer, dataStep, database, dialectFor, emptySnapshot, fieldKinds, fixedClock, generateMigration, makeCleanup, makeMigrations, manifest, migrate, migrateFresh, newSecretKey, not, now, releaseLock, rollback, row, sensitivity, setReleaseStatus, slot, snapshotOf, sqlite, startRelease, structureStep, sync, systemClock };
|
package/dist/db/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { A as Query, C as database, F as systemClock, G as
|
|
3
|
-
import { C as not, F as sensitivity, N as fieldKinds, P as Field, S as count, _ as Total, d as Column, f as Condition, g as Relation, h as Now, m as Expr, r as Model, v as all, w as now, y as any } from "../base64url-
|
|
4
|
-
import { i as slot, n as row, r as Slot, t as createDataLayer } from "../data-layer-
|
|
1
|
+
import { G as ValidationError } from "../validation-Cppmd0RV.js";
|
|
2
|
+
import { A as Query, C as database, F as systemClock, G as DatabaseError, I as newSecretKey, J as UniqueFailed, K as NotFound, M as dialectFor, N as sqlite, P as fixedClock, W as CheckFailed, _ as TODO, b as Database, c as rollback, d as applyRules, g as UnsafeMigration, h as snapshotOf, i as acquireLock, l as setReleaseStatus, m as emptySnapshot, n as migrateFresh, p as generateMigration, q as ReferenceFailed, r as sync, s as releaseLock, t as migrate, u as startRelease, v as dataStep, x as Transaction, y as MigrationError } from "../migrator-BU3_PHk8.js";
|
|
3
|
+
import { C as not, F as sensitivity, N as fieldKinds, P as Field, S as count, _ as Total, d as Column, f as Condition, g as Relation, h as Now, m as Expr, r as Model, v as all, w as now, y as any } from "../base64url-C5GTYIL5.js";
|
|
4
|
+
import { i as slot, n as row, r as Slot, t as createDataLayer } from "../data-layer-_TZtuy-F.js";
|
|
5
5
|
import { t as Seed } from "../seed-BObmdKdP.js";
|
|
6
|
-
import { a as cleanupMigration, i as makeMigrations, r as makeCleanup, t as checkMigrations } from "../make-
|
|
6
|
+
import { a as cleanupMigration, i as makeMigrations, r as makeCleanup, t as checkMigrations } from "../make-DKBn79cH.js";
|
|
7
7
|
//#region src/db/migrations/files.ts
|
|
8
8
|
/** A structure step file: adds tables and columns. Applied once, never edited. */
|
|
9
9
|
function structureStep(options) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as Result, r as Path } from "./issues-
|
|
1
|
+
import { i as Result, r as Path } from "./issues-CKto95IW.js";
|
|
2
2
|
//#region src/validation/standard.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Standard Schema v1 (standardschema.dev), the interface Zod, Valibot and ArkType share. Every
|
|
@@ -39,7 +39,7 @@ interface Measure {
|
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
41
|
* How sensitive a value is: `hidden` never leaves the server; `personal` is redacted in logs,
|
|
42
|
-
* exports and AI context. The output layer applies it
|
|
42
|
+
* exports and AI context. The output layer applies it.
|
|
43
43
|
*/
|
|
44
44
|
type Sensitivity = "hidden" | "personal";
|
|
45
45
|
interface KindSpec {
|
|
@@ -76,7 +76,7 @@ interface KindSpec {
|
|
|
76
76
|
*/
|
|
77
77
|
readonly fake: (fake: Fake, context: FakeContext) => unknown;
|
|
78
78
|
}
|
|
79
|
-
/** What a file kind accepts, and where its files go
|
|
79
|
+
/** What a file kind accepts, and where its files go. */
|
|
80
80
|
interface FileSpec {
|
|
81
81
|
/** The storage its files go to: a key of `storage` in `app.ts`. */
|
|
82
82
|
readonly storage: string;
|
|
@@ -176,7 +176,22 @@ interface StoredFile {
|
|
|
176
176
|
/** An image's size in pixels, when its format says. */
|
|
177
177
|
readonly width?: number;
|
|
178
178
|
readonly height?: number;
|
|
179
|
+
/**
|
|
180
|
+
* An image's smaller copies, each in its own key: the client makes them before uploading (`srcset`
|
|
181
|
+
* picks one). None means the file itself serves every size.
|
|
182
|
+
*/
|
|
183
|
+
readonly sizes?: readonly ImageSize[];
|
|
184
|
+
}
|
|
185
|
+
/** One smaller copy of an image: where it's stored, and what it is. */
|
|
186
|
+
interface ImageSize {
|
|
187
|
+
readonly key: string;
|
|
188
|
+
readonly size: number;
|
|
189
|
+
readonly type: string;
|
|
190
|
+
readonly width: number;
|
|
191
|
+
readonly height: number;
|
|
179
192
|
}
|
|
193
|
+
/** At most this many smaller copies of one image. */
|
|
194
|
+
declare const SIZES_MAX = 4;
|
|
180
195
|
/** File types by their usual name, with the media types each covers. */
|
|
181
196
|
declare const FILE_TYPES: {
|
|
182
197
|
readonly pdf: readonly ["application/pdf"];
|
|
@@ -346,9 +361,8 @@ declare const slug: () => Kind<string, string, false, false>;
|
|
|
346
361
|
*/
|
|
347
362
|
declare const host: () => Kind<string, string, false, false>;
|
|
348
363
|
/**
|
|
349
|
-
* One DNS label for a tenant's host on the platform (`demo` in `demo.thiraiangadi.shop
|
|
350
|
-
*
|
|
351
|
-
* none of the reserved names.
|
|
364
|
+
* One DNS label for a tenant's host on the platform (`demo` in `demo.thiraiangadi.shop`):
|
|
365
|
+
* lowercase letters, digits and inner dashes, 3–63 characters, none of the reserved names.
|
|
352
366
|
*/
|
|
353
367
|
declare const subdomain: () => Kind<string, string, false, false>;
|
|
354
368
|
/** A slug made from text: `"Summer Fest 2026!"` → `"summer-fest-2026"`. Empty when nothing survives. */
|
|
@@ -368,4 +382,4 @@ declare const email: () => Kind<string, string, false, false>;
|
|
|
368
382
|
/** An http(s) URL, up to 2,048 characters. */
|
|
369
383
|
declare const url: () => Kind<string, string, false, false>;
|
|
370
384
|
//#endregion
|
|
371
|
-
export {
|
|
385
|
+
export { images as $, validate as A, money as B, ObjectShape as C, object as D, list as E, datetime as F, FileType as G, sequence as H, fakeUlid as I, SIZES_MAX as J, ImageSize as K, flag as L, IdInput as M, choice as N, serialize as O, date as P, image as Q, id as R, LIST_MAX as S, Shape as T, phone as U, quantity as V, phoneKind as W, file as X, StoredFile as Y, files as Z, define as _, newToken as a, KindSpec as at, CarriesKind as b, slug as c, Sensitivity as ct, text as d, StandardIssue as dt, Fake as et, textKind as f, StandardProps as ft, KindDefinition as g, Definable as h, markdown as i, Kind as it, CalendarDate as j, toKind as k, slugify as l, TypeText as lt, url as m, StandardSchemaV1 as mt, host as n, AnyKind as nt, personName as o, KindTypes as ot, token as p, StandardResult as pt, ImageType as q, line as r, FileSpec as rt, secret as s, Measure as st, email as t, FakeContext as tt, subdomain as u, kind as ut, json as v, Output as w, Input as x, urls as y, int as z };
|
|
@@ -31,7 +31,7 @@ interface AppCore {
|
|
|
31
31
|
readonly seeded: boolean;
|
|
32
32
|
}>;
|
|
33
33
|
}
|
|
34
|
-
/** A tenant's entry points, where its database lives
|
|
34
|
+
/** A tenant's entry points, where its database lives. */
|
|
35
35
|
interface TenantCore {
|
|
36
36
|
/** Brings the tenant's database to the deployed schema: on wake, before any request. */
|
|
37
37
|
wake(): Promise<void>;
|
|
@@ -125,7 +125,7 @@ interface StoredObject {
|
|
|
125
125
|
readonly contentType?: string;
|
|
126
126
|
}
|
|
127
127
|
/**
|
|
128
|
-
* Where files live
|
|
128
|
+
* Where files live. A storage with a `publicUrl` is public: its files are
|
|
129
129
|
* served from there, by the bucket. Without one it's private, and the app serves its files
|
|
130
130
|
* through signed links.
|
|
131
131
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as DatabaseDriver, b as TenantDatabases, d as RateLimiter, g as Storage, l as PdfRenderer, n as Body, p as Runtime, r as Cache, s as MailDriver, u as Queue } from "./index-
|
|
2
|
-
import { C as ObjectShape,
|
|
3
|
-
import { $ as Expr, C as WithIncludes, D as PageOptions, E as Page, J as Models, Q as Embed, S as Key, T as NumberedPageOptions, V as AnyModel, X as Condition, Z as Conditional, b as RowOf, ct as ColumnNode, gt as FieldSpec, i as Row, lt as ConditionNode, n as Patch, p as Database, t as Insert, ut as Operand, v as OrderKey, w as NumberedPage, x as IncludePath } from "./types-
|
|
4
|
-
import { a as PROVIDERS, i as HELD, k as Manifest } from "./data-layer-
|
|
1
|
+
import { a as DatabaseDriver, b as TenantDatabases, d as RateLimiter, g as Storage, l as PdfRenderer, n as Body, p as Runtime, r as Cache, s as MailDriver, u as Queue } from "./index-Ce5p2-EB.js";
|
|
2
|
+
import { C as ObjectShape, Y as StoredFile, w as Output } from "./index-CYcklQ1l.js";
|
|
3
|
+
import { $ as Expr, C as WithIncludes, D as PageOptions, E as Page, J as Models, Q as Embed, S as Key, T as NumberedPageOptions, V as AnyModel, X as Condition, Z as Conditional, b as RowOf, ct as ColumnNode, gt as FieldSpec, i as Row, lt as ConditionNode, n as Patch, p as Database, t as Insert, ut as Operand, v as OrderKey, w as NumberedPage, x as IncludePath } from "./types-S6zF5IXV.js";
|
|
4
|
+
import { a as PROVIDERS, i as HELD, k as Manifest } from "./data-layer-D1BFo3wO.js";
|
|
5
5
|
//#region src/auth/policies.d.ts
|
|
6
6
|
/** The actions every model's policy has. */
|
|
7
7
|
declare const STANDARD_ACTIONS: readonly ["read", "create", "update", "delete"];
|
|
@@ -58,7 +58,7 @@ interface DefinePolicy {
|
|
|
58
58
|
//#region src/api/fail.d.ts
|
|
59
59
|
/**
|
|
60
60
|
* `fail(code, message)`: the app's own business rules, for what can't be a `.check()`, a flow or a
|
|
61
|
-
* unique. Always a 409; app code never picks a status
|
|
61
|
+
* unique. Always a 409; app code never picks a status.
|
|
62
62
|
*/
|
|
63
63
|
declare class Rejected extends Error {
|
|
64
64
|
/** Stable and machine-readable (`alreadyCheckedIn`). */
|
|
@@ -148,7 +148,7 @@ type User = Models extends {
|
|
|
148
148
|
readonly id: string;
|
|
149
149
|
};
|
|
150
150
|
/**
|
|
151
|
-
* Who signs in on the platform's host
|
|
151
|
+
* Who signs in on the platform's host: the `PlatformUser` row,
|
|
152
152
|
* once it's in the `Models` registry.
|
|
153
153
|
*/
|
|
154
154
|
type PlatformUser = Models extends {
|
|
@@ -165,8 +165,8 @@ interface RouteOptions<S extends ObjectShape = ObjectShape, A extends boolean =
|
|
|
165
165
|
/** Callable without a session; `user` is then `User | undefined`. Signed in by default. */
|
|
166
166
|
readonly anonymous?: A;
|
|
167
167
|
/**
|
|
168
|
-
* Served on the platform's host, in the front door, with no tenant (isolated tenancy
|
|
169
|
-
*
|
|
168
|
+
* Served on the platform's host, in the front door, with no tenant (isolated tenancy): `db` is
|
|
169
|
+
* the platform's, `user` a platform user.
|
|
170
170
|
*/
|
|
171
171
|
readonly platform?: Pl;
|
|
172
172
|
}
|
|
@@ -190,13 +190,13 @@ interface RouteContext<P extends string, S extends ObjectShape, A extends boolea
|
|
|
190
190
|
readonly input: Output<S>;
|
|
191
191
|
/** The raw request, for headers. */
|
|
192
192
|
readonly request: Request;
|
|
193
|
-
/** The tenant this request is for
|
|
193
|
+
/** The tenant this request is for; undefined without tenancy, and on the platform's host. */
|
|
194
194
|
readonly tenant: Pl extends true ? undefined : TenantRow;
|
|
195
195
|
}
|
|
196
196
|
type RouteHandler<P extends string, S extends ObjectShape, A extends boolean, R = unknown, Pl extends boolean = false> = (context: RouteContext<P, S, A, Pl>) => R;
|
|
197
197
|
/**
|
|
198
198
|
* One declared route. The pipeline finds these among an app module's exports. `O` is what its
|
|
199
|
-
* handler returns, awaited: the typed client reads it
|
|
199
|
+
* handler returns, awaited: the typed client reads it.
|
|
200
200
|
*/
|
|
201
201
|
declare class Route<O = unknown> {
|
|
202
202
|
readonly method: Method;
|
|
@@ -284,7 +284,7 @@ interface AppConfig {
|
|
|
284
284
|
* `durableObject(env.TENANT)`) and `platform`. Without: one database, named freely (`main`).
|
|
285
285
|
*/
|
|
286
286
|
readonly databases: Readonly<Record<string, DatabaseDriver | TenantDatabases>>;
|
|
287
|
-
/** Many tenants
|
|
287
|
+
/** Many tenants; left out, the app has one. Needs `databases.platform`. */
|
|
288
288
|
readonly tenancy?: TenancyConfig;
|
|
289
289
|
/** Who signs in and how: `auth` from `auth.ts` (createAuth). */
|
|
290
290
|
readonly auth?: Auth<any>;
|
|
@@ -330,11 +330,19 @@ type AnyColumn = {
|
|
|
330
330
|
interface ResourceOptions {
|
|
331
331
|
/** ANDed with the policy for every action (a view's `WHERE`); `byRole` is the action's permission. */
|
|
332
332
|
readonly filter?: Conditional;
|
|
333
|
-
/**
|
|
333
|
+
/**
|
|
334
|
+
* The output: exactly these columns, or `"all"` (hidden kinds never leave either way). Refs and
|
|
335
|
+
* relations are embedded with `.pick(...)`, whose paths may follow relations
|
|
336
|
+
* (`product.variants.pick("price", "tiers.price")`); each level keeps only the rows its own
|
|
337
|
+
* model's `read` rule allows.
|
|
338
|
+
*/
|
|
334
339
|
readonly fields: readonly (AnyColumn | Embed)[] | "all";
|
|
335
340
|
/** Named values computed in SQL (counts, sums, conditions), beside the fields. */
|
|
336
341
|
readonly computed?: Readonly<Record<string, AnyColumn | Condition>>;
|
|
337
|
-
/**
|
|
342
|
+
/**
|
|
343
|
+
* The only fields create and update accept (a mass-assignment guard), or `"all"`. With `create`,
|
|
344
|
+
* it covers every required field without a default.
|
|
345
|
+
*/
|
|
338
346
|
readonly writable?: readonly AnyColumn[] | "all";
|
|
339
347
|
/** Fields (or ref paths: `product.category.slug`) a client may filter by. */
|
|
340
348
|
readonly filterable?: readonly AnyColumn[];
|
|
@@ -342,7 +350,7 @@ interface ResourceOptions {
|
|
|
342
350
|
readonly sortable?: readonly (AnyColumn | string)[];
|
|
343
351
|
/** Named conditions a client switches on: `?onSale`. */
|
|
344
352
|
readonly filters?: Readonly<Record<string, Conditional>>;
|
|
345
|
-
/**
|
|
353
|
+
/** Fields (or ref paths: `product.category.name`) `?search=` matches, any of them, ignoring case. */
|
|
346
354
|
readonly search?: readonly AnyColumn[];
|
|
347
355
|
/** The column `/:key` looks up (unique). The id by default; a singleton has none. */
|
|
348
356
|
readonly key?: AnyColumn;
|
|
@@ -358,7 +366,7 @@ interface SearchField {
|
|
|
358
366
|
}
|
|
359
367
|
/**
|
|
360
368
|
* A declared resource, with what the engine reads from it. `C` is its custom actions, as declared:
|
|
361
|
-
* the typed client reads what each returns
|
|
369
|
+
* the typed client reads what each returns.
|
|
362
370
|
*/
|
|
363
371
|
declare class Resource<C = Readonly<Record<string, CustomAction>>> {
|
|
364
372
|
readonly model: AnyModel;
|
|
@@ -396,6 +404,8 @@ interface PutOptions {
|
|
|
396
404
|
readonly storage?: string;
|
|
397
405
|
/** The body's length in bytes: needed for a stream, read from bytes and text. */
|
|
398
406
|
readonly size?: number;
|
|
407
|
+
/** An image's smaller copies, as bytes (each smaller than it): `srcset` picks one. */
|
|
408
|
+
readonly sizes?: readonly (ArrayBuffer | Uint8Array)[];
|
|
399
409
|
}
|
|
400
410
|
interface AppFiles {
|
|
401
411
|
/** Stores a file (its type read from its bytes) in the current tenant's space, and returns it for a write. */
|
|
@@ -409,7 +419,7 @@ interface AppFiles {
|
|
|
409
419
|
url(file: StoredFile, options?: {
|
|
410
420
|
readonly origin?: string;
|
|
411
421
|
}): Promise<string>;
|
|
412
|
-
/** Removes the file from its storage. */
|
|
422
|
+
/** Removes the file (and its sizes) from its storage. */
|
|
413
423
|
delete(file: StoredFile): Promise<void>;
|
|
414
424
|
}
|
|
415
425
|
//#endregion
|
|
@@ -431,13 +441,13 @@ interface App {
|
|
|
431
441
|
readonly db: Database;
|
|
432
442
|
/**
|
|
433
443
|
* The platform's database (isolated tenancy): for the platform's routes, services and seeds,
|
|
434
|
-
* refused inside a tenant, where `app.db` is the tenant's
|
|
444
|
+
* refused inside a tenant, where `app.db` is the tenant's.
|
|
435
445
|
*/
|
|
436
446
|
readonly platform: {
|
|
437
447
|
readonly db: Database;
|
|
438
448
|
};
|
|
439
449
|
/**
|
|
440
|
-
* Files from code
|
|
450
|
+
* Files from code: `put` stores one for a write (in the current tenant's
|
|
441
451
|
* space), `get` reads it, `url` links to it, `delete` removes it.
|
|
442
452
|
*/
|
|
443
453
|
readonly files: AppFiles;
|
|
@@ -456,7 +466,7 @@ interface AppOptions {
|
|
|
456
466
|
/**
|
|
457
467
|
* The tenant database's history: `() => import("#migrations/tenant")`, through a
|
|
458
468
|
* `#migrations/<name>` alias to `./migrations/<name>/index.ts` in `package.json` imports. Needed with
|
|
459
|
-
* isolated tenancy, where each tenant's database applies it on wake
|
|
469
|
+
* isolated tenancy, where each tenant's database applies it on wake.
|
|
460
470
|
*/
|
|
461
471
|
readonly migrations?: AppMigrations;
|
|
462
472
|
/**
|
|
@@ -480,7 +490,7 @@ interface CreatedApp<Served, TenantHost = undefined> {
|
|
|
480
490
|
*/
|
|
481
491
|
readonly Tenant: TenantHost;
|
|
482
492
|
readonly route: RouteBuilder;
|
|
483
|
-
/** `resource(Model, options)`: what the API exposes over a model
|
|
493
|
+
/** `resource(Model, options)`: what the API exposes over a model. */
|
|
484
494
|
readonly resource: typeof resource;
|
|
485
495
|
readonly fail: typeof fail;
|
|
486
496
|
}
|
|
@@ -491,7 +501,7 @@ interface CreatedApp<Served, TenantHost = undefined> {
|
|
|
491
501
|
declare function createApp<Env, Served, TenantHost = undefined>(runtime: Runtime<Env, Served, TenantHost>, configure: (env: Env) => AppConfig, options?: AppOptions): CreatedApp<Served, TenantHost>;
|
|
492
502
|
//#endregion
|
|
493
503
|
//#region src/app/core.d.ts
|
|
494
|
-
/** The app modules (`apps/*\/routes.ts`, `resources.ts`), each a lazy import
|
|
504
|
+
/** The app modules (`apps/*\/routes.ts`, `resources.ts`), each a lazy import. */
|
|
495
505
|
type AppModules = () => readonly Promise<object>[];
|
|
496
506
|
/**
|
|
497
507
|
* The tenant database's history, as a lazy import of the manifest `isai makemigrations` writes
|
|
@@ -525,7 +535,7 @@ declare class NotImplementedError extends Error {
|
|
|
525
535
|
interface InviteInput {
|
|
526
536
|
readonly email: string;
|
|
527
537
|
readonly role: string;
|
|
528
|
-
/** `"platform"`: the tenant's people can't take the role away
|
|
538
|
+
/** `"platform"`: the tenant's people can't take the role away. */
|
|
529
539
|
readonly held?: (typeof HELD)[number];
|
|
530
540
|
}
|
|
531
541
|
//#endregion
|
|
@@ -556,8 +566,10 @@ interface AuthDefinition {
|
|
|
556
566
|
/** Who may make an account by signing in: anyone (`"open"`, the default), or the invited. */
|
|
557
567
|
readonly signUp?: "open" | "invite";
|
|
558
568
|
/**
|
|
559
|
-
* Signs what crosses the browser during sign-in (Google's `state`, the hand-off between hosts)
|
|
560
|
-
* 32 random bytes, base64url, kept as a secret of the deployment
|
|
569
|
+
* Signs what crosses the browser during sign-in (Google's `state`, the hand-off between hosts)
|
|
570
|
+
* and private files' links: 32 random bytes, base64url, kept as a secret of the deployment
|
|
571
|
+
* (`env.AUTH_SECRET`). Sessions don't depend on it, so rotating it only ends sign-ins in progress
|
|
572
|
+
* and links already given out.
|
|
561
573
|
*/
|
|
562
574
|
readonly secret: string;
|
|
563
575
|
}
|
|
@@ -580,7 +592,7 @@ declare class Auth<Env = unknown> {
|
|
|
580
592
|
readonly invite: "auth.invite";
|
|
581
593
|
/** See the people with accounts, give and take their roles, suspend them. */
|
|
582
594
|
readonly manageUsers: "auth.manageUsers";
|
|
583
|
-
/** Read the whole audit log (`GET /api/audit`), with the log on
|
|
595
|
+
/** Read the whole audit log (`GET /api/audit`), with the log on. */
|
|
584
596
|
readonly readAudit: "audit.read";
|
|
585
597
|
};
|
|
586
598
|
/** The policies made with this instance's `policy()`. */
|
|
@@ -591,7 +603,7 @@ declare class Auth<Env = unknown> {
|
|
|
591
603
|
/**
|
|
592
604
|
* Gives `email` a role from `app.ts`, from code (a tenant's setup service, a seed): now, if it has
|
|
593
605
|
* an account in the current database, else when it first signs in. Safe to repeat.
|
|
594
|
-
* `held: "platform"` puts the assignment beyond the tenant's reach
|
|
606
|
+
* `held: "platform"` puts the assignment beyond the tenant's reach.
|
|
595
607
|
*/
|
|
596
608
|
invite(input: InviteInput): Promise<void>;
|
|
597
609
|
/** The core's: where `invite` writes. */
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { p as Runtime, t as AppCore } from "./index-
|
|
2
|
-
import { C as Params, D as RouteHandler, E as RouteContext, M as fail, O as RouteOptions, S as Method, T as RouteBuilder, _ as CustomAction, b as AppConfig, d as NotImplementedError, f as AppModules, g as createApp, h as CreatedApp, j as Rejected, k as User, m as AppOptions, p as App, v as Resource, w as Route, x as Named, y as ResourceOptions } from "./index-
|
|
1
|
+
import { p as Runtime, t as AppCore } from "./index-Ce5p2-EB.js";
|
|
2
|
+
import { C as Params, D as RouteHandler, E as RouteContext, M as fail, O as RouteOptions, S as Method, T as RouteBuilder, _ as CustomAction, b as AppConfig, d as NotImplementedError, f as AppModules, g as createApp, h as CreatedApp, j as Rejected, k as User, m as AppOptions, p as App, v as Resource, w as Route, x as Named, y as ResourceOptions } from "./index-DlgVg3D8.js";
|
|
3
3
|
export { type App, type AppConfig, type AppCore, type AppModules, type AppOptions, type CreatedApp, type CustomAction, type Method, type Named, NotImplementedError, type Params, Rejected, type Resource, type ResourceOptions, Route, type RouteBuilder, type RouteContext, type RouteHandler, type RouteOptions, type Runtime, type User, createApp, fail };
|