lazypock 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -413,6 +413,8 @@ interface SchemaField {
413
413
  id?: string;
414
414
  name: string;
415
415
  type: string;
416
+ /** For relation fields: the target collection id (server-resolved). */
417
+ collectionId?: string | null;
416
418
  required?: boolean;
417
419
  unique?: boolean;
418
420
  options?: {
@@ -465,8 +467,9 @@ declare class CollectionService<T = ApiRecord> {
465
467
  private schema?;
466
468
  /**
467
469
  * Active field projection from {@link select}. `"*"` (or unset) means
468
- * "all visible (non-hidden) fields" — resolved against the schema when
469
- * one is available, otherwise left to the server.
470
+ * "all visible (non-hidden) fields plus the implicit system keys" —
471
+ * resolved against the schema when one is available, otherwise left to
472
+ * the server.
470
473
  */
471
474
  private fieldsPreset?;
472
475
  /** @internal */
@@ -484,9 +487,10 @@ declare class CollectionService<T = ApiRecord> {
484
487
  * const t = await client.collection("posts").select("id", "title").getList();
485
488
  * // GET /api/posts?fields=id,title
486
489
  *
487
- * // All visible fields (hidden fields are excluded server-side)
490
+ * // All visible fields (implicit system keys id/created/updated/… are
491
+ * // kept; hidden fields are excluded via the projection)
488
492
  * const all = await client.collection("posts").select("*").getList();
489
- * // GET /api/posts?fields=id,title,published,… (schema known)
493
+ * // GET /api/posts?fields=id,created,updated,collectionId,collectionName,title,published,… (schema known)
490
494
  * ```
491
495
  *
492
496
  * When no schema is known, the default (no `select()` call) sends no
@@ -498,12 +502,23 @@ declare class CollectionService<T = ApiRecord> {
498
502
  * Fields to send with reads:
499
503
  * 1. explicit `options.fields` (caller wins)
500
504
  * 2. `select()` preset
501
- * 3. schema default — all visible (non-hidden, non-system) fields
505
+ * 3. schema default — all visible (non-hidden) fields plus the implicit
506
+ * system keys (`id`, `created`, `updated`, `collectionId`, `collectionName`)
502
507
  */
503
508
  private effectiveFields;
504
509
  /**
505
- * All non-hidden, non-system, non-password field names from the schema.
506
- * `undefined` when no schema is available (server decides).
510
+ * All non-hidden, non-password, non-autodate field names from the schema,
511
+ * prefixed with the implicit system keys that are part of every record
512
+ * (`id`, `created`, `updated`, `collectionId`, `collectionName`).
513
+ *
514
+ * The system keys never appear in the schema (they are implied for every
515
+ * collection) but MUST be listed explicitly when projecting — the server
516
+ * applies strict projection, so unrequested fields are dropped. Without
517
+ * them, `getList`/`getOne` responses lose `id` (and `created`/`updated`),
518
+ * breaking selection, edits, and relation references.
519
+ *
520
+ * `undefined` when no schema fields are available (server decides — its
521
+ * default returns every non-password field, including the system keys).
507
522
  */
508
523
  visibleFields(): string | undefined;
509
524
  /** Warn once when an expand field is not a relation (schema known). */
@@ -865,6 +880,14 @@ interface LazypockClientOptions {
865
880
  declare class LazypockClient {
866
881
  readonly http: HttpClient;
867
882
  readonly authStore: AuthStore;
883
+ /**
884
+ * Resolves once persisted auth state has been loaded from storage.
885
+ * The client auto-initializes its auth store on construction, so a
886
+ * previously persisted token is ready immediately (no manual
887
+ * `authStore.init()` needed). Await this only if you must gate on
888
+ * the restored session.
889
+ */
890
+ readonly authReady: Promise<void>;
868
891
  readonly realtime: RealtimeService;
869
892
  readonly collections: CollectionsService;
870
893
  readonly files: FilesService;
package/dist/index.d.ts CHANGED
@@ -413,6 +413,8 @@ interface SchemaField {
413
413
  id?: string;
414
414
  name: string;
415
415
  type: string;
416
+ /** For relation fields: the target collection id (server-resolved). */
417
+ collectionId?: string | null;
416
418
  required?: boolean;
417
419
  unique?: boolean;
418
420
  options?: {
@@ -465,8 +467,9 @@ declare class CollectionService<T = ApiRecord> {
465
467
  private schema?;
466
468
  /**
467
469
  * Active field projection from {@link select}. `"*"` (or unset) means
468
- * "all visible (non-hidden) fields" — resolved against the schema when
469
- * one is available, otherwise left to the server.
470
+ * "all visible (non-hidden) fields plus the implicit system keys" —
471
+ * resolved against the schema when one is available, otherwise left to
472
+ * the server.
470
473
  */
471
474
  private fieldsPreset?;
472
475
  /** @internal */
@@ -484,9 +487,10 @@ declare class CollectionService<T = ApiRecord> {
484
487
  * const t = await client.collection("posts").select("id", "title").getList();
485
488
  * // GET /api/posts?fields=id,title
486
489
  *
487
- * // All visible fields (hidden fields are excluded server-side)
490
+ * // All visible fields (implicit system keys id/created/updated/… are
491
+ * // kept; hidden fields are excluded via the projection)
488
492
  * const all = await client.collection("posts").select("*").getList();
489
- * // GET /api/posts?fields=id,title,published,… (schema known)
493
+ * // GET /api/posts?fields=id,created,updated,collectionId,collectionName,title,published,… (schema known)
490
494
  * ```
491
495
  *
492
496
  * When no schema is known, the default (no `select()` call) sends no
@@ -498,12 +502,23 @@ declare class CollectionService<T = ApiRecord> {
498
502
  * Fields to send with reads:
499
503
  * 1. explicit `options.fields` (caller wins)
500
504
  * 2. `select()` preset
501
- * 3. schema default — all visible (non-hidden, non-system) fields
505
+ * 3. schema default — all visible (non-hidden) fields plus the implicit
506
+ * system keys (`id`, `created`, `updated`, `collectionId`, `collectionName`)
502
507
  */
503
508
  private effectiveFields;
504
509
  /**
505
- * All non-hidden, non-system, non-password field names from the schema.
506
- * `undefined` when no schema is available (server decides).
510
+ * All non-hidden, non-password, non-autodate field names from the schema,
511
+ * prefixed with the implicit system keys that are part of every record
512
+ * (`id`, `created`, `updated`, `collectionId`, `collectionName`).
513
+ *
514
+ * The system keys never appear in the schema (they are implied for every
515
+ * collection) but MUST be listed explicitly when projecting — the server
516
+ * applies strict projection, so unrequested fields are dropped. Without
517
+ * them, `getList`/`getOne` responses lose `id` (and `created`/`updated`),
518
+ * breaking selection, edits, and relation references.
519
+ *
520
+ * `undefined` when no schema fields are available (server decides — its
521
+ * default returns every non-password field, including the system keys).
507
522
  */
508
523
  visibleFields(): string | undefined;
509
524
  /** Warn once when an expand field is not a relation (schema known). */
@@ -865,6 +880,14 @@ interface LazypockClientOptions {
865
880
  declare class LazypockClient {
866
881
  readonly http: HttpClient;
867
882
  readonly authStore: AuthStore;
883
+ /**
884
+ * Resolves once persisted auth state has been loaded from storage.
885
+ * The client auto-initializes its auth store on construction, so a
886
+ * previously persisted token is ready immediately (no manual
887
+ * `authStore.init()` needed). Await this only if you must gate on
888
+ * the restored session.
889
+ */
890
+ readonly authReady: Promise<void>;
868
891
  readonly realtime: RealtimeService;
869
892
  readonly collections: CollectionsService;
870
893
  readonly files: FilesService;
@@ -519,9 +519,10 @@ var Lazypock = (() => {
519
519
  * const t = await client.collection("posts").select("id", "title").getList();
520
520
  * // GET /api/posts?fields=id,title
521
521
  *
522
- * // All visible fields (hidden fields are excluded server-side)
522
+ * // All visible fields (implicit system keys id/created/updated/… are
523
+ * // kept; hidden fields are excluded via the projection)
523
524
  * const all = await client.collection("posts").select("*").getList();
524
- * // GET /api/posts?fields=id,title,published,… (schema known)
525
+ * // GET /api/posts?fields=id,created,updated,collectionId,collectionName,title,published,… (schema known)
525
526
  * ```
526
527
  *
527
528
  * When no schema is known, the default (no `select()` call) sends no
@@ -554,7 +555,8 @@ var Lazypock = (() => {
554
555
  * Fields to send with reads:
555
556
  * 1. explicit `options.fields` (caller wins)
556
557
  * 2. `select()` preset
557
- * 3. schema default — all visible (non-hidden, non-system) fields
558
+ * 3. schema default — all visible (non-hidden) fields plus the implicit
559
+ * system keys (`id`, `created`, `updated`, `collectionId`, `collectionName`)
558
560
  */
559
561
  effectiveFields(optionsFields) {
560
562
  if (optionsFields !== void 0) return optionsFields;
@@ -567,15 +569,35 @@ var Lazypock = (() => {
567
569
  return this.visibleFields();
568
570
  }
569
571
  /**
570
- * All non-hidden, non-system, non-password field names from the schema.
571
- * `undefined` when no schema is available (server decides).
572
+ * All non-hidden, non-password, non-autodate field names from the schema,
573
+ * prefixed with the implicit system keys that are part of every record
574
+ * (`id`, `created`, `updated`, `collectionId`, `collectionName`).
575
+ *
576
+ * The system keys never appear in the schema (they are implied for every
577
+ * collection) but MUST be listed explicitly when projecting — the server
578
+ * applies strict projection, so unrequested fields are dropped. Without
579
+ * them, `getList`/`getOne` responses lose `id` (and `created`/`updated`),
580
+ * breaking selection, edits, and relation references.
581
+ *
582
+ * `undefined` when no schema fields are available (server decides — its
583
+ * default returns every non-password field, including the system keys).
572
584
  */
573
585
  visibleFields() {
574
586
  if (!this.schema?.fields) return void 0;
575
587
  const visible = this.schema.fields.filter(
576
588
  (f) => !f.hidden && f.type !== "password" && f.type !== "autodate"
577
589
  ).map((f) => f.name);
578
- return visible.length > 0 ? visible.join(",") : void 0;
590
+ if (visible.length === 0) return void 0;
591
+ return [
592
+ .../* @__PURE__ */ new Set([
593
+ "id",
594
+ "created",
595
+ "updated",
596
+ "collectionId",
597
+ "collectionName",
598
+ ...visible
599
+ ])
600
+ ].join(",");
579
601
  }
580
602
  /** Warn once when an expand field is not a relation (schema known). */
581
603
  validateExpand(expand) {
@@ -1508,10 +1530,13 @@ export function createClient(options: LazypockClientOptions): TypedClient {
1508
1530
  }
1509
1531
 
1510
1532
  export class TypedClient extends LazypockClient {
1511
- override collection<T extends string>(name: T): T extends keyof LazypockCollections
1512
- ? CollectionService<LazypockCollections[T]>
1513
- : CollectionService<unknown> {
1514
- return super.collection(name) as T extends keyof LazypockCollections ? CollectionService<LazypockCollections[T]> : CollectionService<unknown>;
1533
+ // K extends keyof LazypockCollections (rather than a generic string with a
1534
+ // conditional return) so the IDE suggests collection names and unknown names
1535
+ // are rejected at compile time:
1536
+ // client.collection("posts") // suggested + typed
1537
+ // client.collection("nope") // TS error
1538
+ override collection<K extends keyof LazypockCollections>(name: K): CollectionService<LazypockCollections[K]> {
1539
+ return super.collection(name) as CollectionService<LazypockCollections[K]>;
1515
1540
  }
1516
1541
  }
1517
1542
  `);
@@ -1543,6 +1568,7 @@ ${opts.body}
1543
1568
  this.collectionCache = /* @__PURE__ */ new Map();
1544
1569
  const baseUrl = options.baseUrl.replace(/\/+$/, "");
1545
1570
  this.authStore = options.authStore ?? new AuthStore(options.storage ?? memoryStorage);
1571
+ this.authReady = options.authStore ? Promise.resolve() : this.authStore.init();
1546
1572
  this.http = new HttpClient(baseUrl, this.authStore);
1547
1573
  this.realtime = options.realtime ?? new RealtimeService();
1548
1574
  if (!options.realtime) {