lazypock 0.7.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/dist/{chunk-HOBNUW5Z.js → chunk-BJQUGPKE.js} +33 -5
- package/dist/chunk-BJQUGPKE.js.map +1 -0
- package/dist/cli.cjs +32 -4
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.global.js +32 -4
- package/dist/cli.global.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/index.cjs +61 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -12
- package/dist/index.d.ts +35 -12
- package/dist/index.global.js +61 -10
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +30 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/codegen.ts +53 -4
- package/src/collection.ts +47 -15
- package/src/lazypock.ts +14 -0
- package/src/schema.ts +2 -0
- package/dist/chunk-HOBNUW5Z.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -519,9 +519,10 @@ var CollectionService = class _CollectionService {
|
|
|
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 (
|
|
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 CollectionService = class _CollectionService {
|
|
|
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
|
|
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 CollectionService = class _CollectionService {
|
|
|
567
569
|
return this.visibleFields();
|
|
568
570
|
}
|
|
569
571
|
/**
|
|
570
|
-
* All non-hidden, non-
|
|
571
|
-
*
|
|
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
|
-
|
|
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) {
|
|
@@ -1461,6 +1483,12 @@ function generateTypes(collections, options = {}) {
|
|
|
1461
1483
|
body
|
|
1462
1484
|
})}`
|
|
1463
1485
|
);
|
|
1486
|
+
const createLines = fields.map((f) => createDataMemberLine(f)).filter((l) => l !== "");
|
|
1487
|
+
sections.push(
|
|
1488
|
+
`export interface ${typeName}CreateData${renderInterface({
|
|
1489
|
+
body: createLines.join("\n")
|
|
1490
|
+
})}`
|
|
1491
|
+
);
|
|
1464
1492
|
}
|
|
1465
1493
|
sections.push(`export interface AuthRecord extends BaseRecord {
|
|
1466
1494
|
email: string;
|
|
@@ -1471,6 +1499,10 @@ function generateTypes(collections, options = {}) {
|
|
|
1471
1499
|
).join("\n");
|
|
1472
1500
|
sections.push(`export interface LazypockCollections {
|
|
1473
1501
|
${mapEntries}
|
|
1502
|
+
}`);
|
|
1503
|
+
const createMapEntries = filtered.map((c) => ` "${c.name}": ${collectionTypeName(c.name)}CreateData;`).join("\n");
|
|
1504
|
+
sections.push(`export interface LazypockCreateData {
|
|
1505
|
+
${createMapEntries}
|
|
1474
1506
|
}`);
|
|
1475
1507
|
const schemaEntries = collections.map(
|
|
1476
1508
|
(c) => ` {
|
|
@@ -1494,6 +1526,10 @@ ${schemaEntries}
|
|
|
1494
1526
|
* Collection access is fully type-checked:
|
|
1495
1527
|
* client.collection("posts").create({ title: "x" }) // title must exist
|
|
1496
1528
|
*
|
|
1529
|
+
* For auth collections the generated *CreateData type includes the
|
|
1530
|
+
* write-only password field, so creating a user is type-safe:
|
|
1531
|
+
* client.collection("users").create({ email, password }) // \u2713
|
|
1532
|
+
*
|
|
1497
1533
|
* The schema snapshot is wired into the client automatically, so hidden
|
|
1498
1534
|
* fields are excluded from responses and select/expand are validated.
|
|
1499
1535
|
*/
|
|
@@ -1508,10 +1544,16 @@ export function createClient(options: LazypockClientOptions): TypedClient {
|
|
|
1508
1544
|
}
|
|
1509
1545
|
|
|
1510
1546
|
export class TypedClient extends LazypockClient {
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1547
|
+
// K extends keyof LazypockCollections (rather than a generic string with a
|
|
1548
|
+
// conditional return) so the IDE suggests collection names and unknown names
|
|
1549
|
+
// are rejected at compile time:
|
|
1550
|
+
// client.collection("posts") // suggested + typed
|
|
1551
|
+
// client.collection("nope") // TS error
|
|
1552
|
+
//
|
|
1553
|
+
// create()/update() take the collection's *CreateData \u2014 the read model
|
|
1554
|
+
// omits password/hidden fields, but the write model carries them.
|
|
1555
|
+
override collection<K extends keyof LazypockCollections>(name: K): CollectionService<LazypockCollections[K], LazypockCreateData[K]> {
|
|
1556
|
+
return super.collection(name) as CollectionService<LazypockCollections[K], LazypockCreateData[K]>;
|
|
1515
1557
|
}
|
|
1516
1558
|
}
|
|
1517
1559
|
`);
|
|
@@ -1532,6 +1574,14 @@ function memberLine(f) {
|
|
|
1532
1574
|
if (type === "never") return "";
|
|
1533
1575
|
return ` ${JSON.stringify(key)}${req}: ${type};`;
|
|
1534
1576
|
}
|
|
1577
|
+
function createDataMemberLine(f) {
|
|
1578
|
+
if (f.type === "autodate") return "";
|
|
1579
|
+
const key = fieldKey(f.name);
|
|
1580
|
+
const req = f.required ? "" : "?";
|
|
1581
|
+
const type = f.type === "password" ? "string" : fieldTypeScriptType(f);
|
|
1582
|
+
if (type === "never") return "";
|
|
1583
|
+
return ` ${JSON.stringify(key)}${req}: ${type};`;
|
|
1584
|
+
}
|
|
1535
1585
|
|
|
1536
1586
|
// src/lazypock.ts
|
|
1537
1587
|
var LazypockClient = class {
|
|
@@ -1543,6 +1593,7 @@ var LazypockClient = class {
|
|
|
1543
1593
|
this.collectionCache = /* @__PURE__ */ new Map();
|
|
1544
1594
|
const baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
1545
1595
|
this.authStore = options.authStore ?? new AuthStore(options.storage ?? memoryStorage);
|
|
1596
|
+
this.authReady = options.authStore ? Promise.resolve() : this.authStore.init();
|
|
1546
1597
|
this.http = new HttpClient(baseUrl, this.authStore);
|
|
1547
1598
|
this.realtime = options.realtime ?? new RealtimeService();
|
|
1548
1599
|
if (!options.realtime) {
|