@org-quicko/silo-client 1.0.0 → 1.0.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 +159 -124
- package/dist/collections/collection-handle.d.cts +15 -23
- package/dist/collections/collection-handle.d.ts +15 -23
- package/dist/collections/collections.d.cts +3 -5
- package/dist/collections/collections.d.ts +3 -5
- package/dist/entries/entry-envelope.d.cts +18 -0
- package/dist/entries/entry-envelope.d.ts +18 -0
- package/dist/entries/entry-read-options.d.cts +16 -0
- package/dist/entries/entry-read-options.d.ts +16 -0
- package/dist/entries/entry-reader.d.cts +16 -16
- package/dist/entries/entry-reader.d.ts +16 -16
- package/dist/entries/entry.d.cts +11 -23
- package/dist/entries/entry.d.ts +11 -23
- package/dist/index.cjs +29 -153
- package/dist/index.d.cts +3 -5
- package/dist/index.d.ts +3 -5
- package/dist/index.js +29 -153
- package/dist/search/search-hit.d.cts +5 -5
- package/dist/search/search-hit.d.ts +5 -5
- package/dist/search/search.d.cts +4 -1
- package/dist/search/search.d.ts +4 -1
- package/package.json +58 -58
- package/dist/collections/reserved-field-names.d.cts +0 -9
- package/dist/collections/reserved-field-names.d.ts +0 -9
- package/dist/entries/entry-base.d.cts +0 -31
- package/dist/entries/entry-base.d.ts +0 -31
- package/dist/entries/entry-mapper.d.cts +0 -13
- package/dist/entries/entry-mapper.d.ts +0 -13
- package/dist/entries/entry-payload.d.cts +0 -12
- package/dist/entries/entry-payload.d.ts +0 -12
- package/dist/entries/resolved-entry.d.cts +0 -11
- package/dist/entries/resolved-entry.d.ts +0 -11
package/dist/index.js
CHANGED
|
@@ -678,96 +678,6 @@ class ProjectVariables {
|
|
|
678
678
|
}
|
|
679
679
|
}
|
|
680
680
|
|
|
681
|
-
// src/entries/entry-mapper.ts
|
|
682
|
-
class EntryMapper {
|
|
683
|
-
static fieldsOf(payload) {
|
|
684
|
-
const { id: _id, rev: _rev, created_at: _createdAt, updated_at: _updatedAt, ...fields } = payload;
|
|
685
|
-
return fields;
|
|
686
|
-
}
|
|
687
|
-
static toPayload(id, rev, fields, createdAt, updatedAt) {
|
|
688
|
-
return {
|
|
689
|
-
id,
|
|
690
|
-
rev,
|
|
691
|
-
...fields,
|
|
692
|
-
created_at: createdAt.toISOString(),
|
|
693
|
-
updated_at: updatedAt.toISOString()
|
|
694
|
-
};
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
// src/entries/entry-base.ts
|
|
699
|
-
class EntryBase {
|
|
700
|
-
context;
|
|
701
|
-
id;
|
|
702
|
-
rev;
|
|
703
|
-
createdAt;
|
|
704
|
-
updatedAt;
|
|
705
|
-
fields;
|
|
706
|
-
constructor(context, payload) {
|
|
707
|
-
this.context = context;
|
|
708
|
-
this.id = String(payload.id);
|
|
709
|
-
this.rev = Number(payload.rev);
|
|
710
|
-
this.createdAt = new Date(payload.created_at);
|
|
711
|
-
this.updatedAt = new Date(payload.updated_at);
|
|
712
|
-
this.fields = EntryMapper.fieldsOf(payload);
|
|
713
|
-
}
|
|
714
|
-
toJSON() {
|
|
715
|
-
return EntryMapper.toPayload(this.id, this.rev, this.fields, this.createdAt, this.updatedAt);
|
|
716
|
-
}
|
|
717
|
-
async delete(options = {}) {
|
|
718
|
-
await this.context.transport.empty({
|
|
719
|
-
method: "DELETE",
|
|
720
|
-
path: ApiPath.entry(this.context.project, this.context.environment, this.context.collection, this.id),
|
|
721
|
-
query: { rev: this.rev },
|
|
722
|
-
...options
|
|
723
|
-
});
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
// src/entries/resolved-entry.ts
|
|
728
|
-
class ResolvedEntry extends EntryBase {
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
// src/entries/entry.ts
|
|
732
|
-
class Entry extends ResolvedEntry {
|
|
733
|
-
saving = false;
|
|
734
|
-
async save(options = {}) {
|
|
735
|
-
if (this.saving) {
|
|
736
|
-
throw new Error(`cannot save entry "${this.id}": a previous save() on this instance has not finished yet`);
|
|
737
|
-
}
|
|
738
|
-
this.saving = true;
|
|
739
|
-
try {
|
|
740
|
-
const payload = await this.context.transport.json({
|
|
741
|
-
method: "PUT",
|
|
742
|
-
path: ApiPath.entry(this.context.project, this.context.environment, this.context.collection, this.id),
|
|
743
|
-
query: { rev: this.rev, variables: "raw" },
|
|
744
|
-
body: this.fields,
|
|
745
|
-
...options
|
|
746
|
-
});
|
|
747
|
-
this.adopt(payload);
|
|
748
|
-
return this;
|
|
749
|
-
} finally {
|
|
750
|
-
this.saving = false;
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
async refresh(options = {}) {
|
|
754
|
-
const payload = await this.context.transport.json({
|
|
755
|
-
method: "GET",
|
|
756
|
-
path: ApiPath.entry(this.context.project, this.context.environment, this.context.collection, this.id),
|
|
757
|
-
query: { variables: "raw" },
|
|
758
|
-
...options
|
|
759
|
-
});
|
|
760
|
-
this.adopt(payload);
|
|
761
|
-
return this;
|
|
762
|
-
}
|
|
763
|
-
adopt(payload) {
|
|
764
|
-
this.rev = Number(payload.rev);
|
|
765
|
-
this.createdAt = new Date(payload.created_at);
|
|
766
|
-
this.updatedAt = new Date(payload.updated_at);
|
|
767
|
-
this.fields = EntryMapper.fieldsOf(payload);
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
|
|
771
681
|
// src/transport/page-payload.ts
|
|
772
682
|
class PagePayload {
|
|
773
683
|
static read(body) {
|
|
@@ -828,40 +738,39 @@ class EntryStream extends RowStream {
|
|
|
828
738
|
|
|
829
739
|
// src/entries/entry-reader.ts
|
|
830
740
|
class EntryReader {
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
this.
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
const payload = await this.context.transport.json({
|
|
741
|
+
scope;
|
|
742
|
+
collection;
|
|
743
|
+
constructor(scope, collection) {
|
|
744
|
+
this.scope = scope;
|
|
745
|
+
this.collection = collection;
|
|
746
|
+
}
|
|
747
|
+
get(id, options = {}) {
|
|
748
|
+
const { variables, ...request } = options;
|
|
749
|
+
return this.scope.transport.json({
|
|
841
750
|
method: "GET",
|
|
842
|
-
path: ApiPath.entry(this.
|
|
843
|
-
query: { variables
|
|
844
|
-
...
|
|
751
|
+
path: ApiPath.entry(this.scope.project, this.scope.environment, this.collection, id),
|
|
752
|
+
query: { variables },
|
|
753
|
+
...request
|
|
845
754
|
});
|
|
846
|
-
return this.wrap(payload);
|
|
847
755
|
}
|
|
848
756
|
async list(query = {}, options = {}) {
|
|
757
|
+
const { variables, ...request } = options;
|
|
849
758
|
const loader = (window2) => this.list({ ...query, limit: window2.limit, offset: window2.offset }, options);
|
|
850
|
-
const body = await this.
|
|
759
|
+
const body = await this.scope.transport.json({
|
|
851
760
|
method: "GET",
|
|
852
|
-
path: ApiPath.entries(this.
|
|
761
|
+
path: ApiPath.entries(this.scope.project, this.scope.environment, this.collection),
|
|
853
762
|
query: {
|
|
854
763
|
limit: query.limit,
|
|
855
764
|
offset: query.offset,
|
|
856
765
|
filter: query.where?.toJSON(),
|
|
857
766
|
sort: query.sort === undefined ? undefined : String(query.sort),
|
|
858
|
-
variables
|
|
767
|
+
variables
|
|
859
768
|
},
|
|
860
|
-
...
|
|
769
|
+
...request
|
|
861
770
|
});
|
|
862
771
|
const page = PagePayload.read(body);
|
|
863
772
|
const window = new PageWindow(page.limit ?? query.limit ?? 50, page.offset ?? query.offset ?? 0);
|
|
864
|
-
return new EntryPage(page.rows
|
|
773
|
+
return new EntryPage(page.rows, page.total, window, loader);
|
|
865
774
|
}
|
|
866
775
|
all(query = {}, options = {}) {
|
|
867
776
|
const loader = async (window) => {
|
|
@@ -1035,15 +944,15 @@ class Search {
|
|
|
1035
944
|
const window = new PageWindow(page.limit ?? query.limit ?? 50, page.offset ?? query.offset ?? 0);
|
|
1036
945
|
const truncated = body.truncated === true;
|
|
1037
946
|
const engine = body.engine;
|
|
1038
|
-
const hits = page.rows.map((hit) =>
|
|
947
|
+
const hits = page.rows.map((hit) => Search.toHit(hit));
|
|
1039
948
|
return new SearchPage(hits, page.total, window, truncated, engine, loader);
|
|
1040
949
|
}
|
|
1041
|
-
toHit(payload) {
|
|
950
|
+
static toHit(payload) {
|
|
1042
951
|
return {
|
|
1043
952
|
project: payload.project,
|
|
1044
953
|
environment: payload.env,
|
|
1045
954
|
collection: payload.collection,
|
|
1046
|
-
entry:
|
|
955
|
+
entry: payload.entry,
|
|
1047
956
|
snippets: payload.snippets
|
|
1048
957
|
};
|
|
1049
958
|
}
|
|
@@ -1106,36 +1015,24 @@ class CollectionHandle {
|
|
|
1106
1015
|
name;
|
|
1107
1016
|
filter = new TypedFilter;
|
|
1108
1017
|
schema;
|
|
1109
|
-
|
|
1110
|
-
context;
|
|
1111
|
-
resolved;
|
|
1018
|
+
reader;
|
|
1112
1019
|
constructor(scope, name) {
|
|
1113
1020
|
this.scope = scope;
|
|
1114
1021
|
this.name = name;
|
|
1115
1022
|
this.schema = new CollectionSchema(scope, name);
|
|
1116
|
-
this.
|
|
1117
|
-
transport: scope.transport,
|
|
1118
|
-
project: scope.project,
|
|
1119
|
-
environment: scope.environment,
|
|
1120
|
-
collection: name
|
|
1121
|
-
};
|
|
1122
|
-
this.resolved = new EntryReader(this.context, undefined, (payload) => new ResolvedEntry(this.context, payload));
|
|
1123
|
-
this.editable = new EntryReader(this.context, "raw", (payload) => new Entry(this.context, payload));
|
|
1023
|
+
this.reader = new EntryReader(scope, name);
|
|
1124
1024
|
}
|
|
1125
1025
|
get(id, options = {}) {
|
|
1126
|
-
return this.
|
|
1127
|
-
}
|
|
1128
|
-
edit(id, options = {}) {
|
|
1129
|
-
return this.editable.get(id, options);
|
|
1026
|
+
return this.reader.get(id, options);
|
|
1130
1027
|
}
|
|
1131
1028
|
list(query = {}, options = {}) {
|
|
1132
|
-
return this.
|
|
1029
|
+
return this.reader.list(query, options);
|
|
1133
1030
|
}
|
|
1134
1031
|
all(query = {}, options = {}) {
|
|
1135
|
-
return this.
|
|
1032
|
+
return this.reader.all(query, options);
|
|
1136
1033
|
}
|
|
1137
1034
|
pages(query = {}, options = {}) {
|
|
1138
|
-
return this.
|
|
1035
|
+
return this.reader.pages(query, options);
|
|
1139
1036
|
}
|
|
1140
1037
|
create(fields, options = {}) {
|
|
1141
1038
|
return this.write("POST", ApiPath.entries(this.scope.project, this.scope.environment, this.name), fields, undefined, options);
|
|
@@ -1165,23 +1062,14 @@ class CollectionHandle {
|
|
|
1165
1062
|
});
|
|
1166
1063
|
return RenameReport.fromWire(payload);
|
|
1167
1064
|
}
|
|
1168
|
-
|
|
1169
|
-
|
|
1065
|
+
write(method, path, fields, rev, options) {
|
|
1066
|
+
return this.scope.transport.json({
|
|
1170
1067
|
method,
|
|
1171
1068
|
path,
|
|
1172
1069
|
query: { rev, variables: "raw" },
|
|
1173
1070
|
body: fields,
|
|
1174
1071
|
...options
|
|
1175
1072
|
});
|
|
1176
|
-
return new Entry(this.context, payload);
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
|
|
1180
|
-
// src/collections/reserved-field-names.ts
|
|
1181
|
-
class ReservedFieldNames {
|
|
1182
|
-
static all = ["id", "rev", "seq", "created_at", "updated_at"];
|
|
1183
|
-
static isReserved(name) {
|
|
1184
|
-
return ReservedFieldNames.all.includes(name);
|
|
1185
1073
|
}
|
|
1186
1074
|
}
|
|
1187
1075
|
|
|
@@ -1200,7 +1088,6 @@ class Collections {
|
|
|
1200
1088
|
return body.items.map(Collections.toSummary);
|
|
1201
1089
|
}
|
|
1202
1090
|
async create(name, schema, options = {}) {
|
|
1203
|
-
Collections.warnOnReservedFields(schema);
|
|
1204
1091
|
return this.scope.transport.json({
|
|
1205
1092
|
method: "POST",
|
|
1206
1093
|
path: ApiPath.collections(this.scope.project, this.scope.environment),
|
|
@@ -1218,13 +1105,6 @@ class Collections {
|
|
|
1218
1105
|
updatedAt: new Date(payload.updated_at)
|
|
1219
1106
|
};
|
|
1220
1107
|
}
|
|
1221
|
-
static warnOnReservedFields(schema) {
|
|
1222
|
-
for (const name of Object.keys(schema.properties ?? {})) {
|
|
1223
|
-
if (ReservedFieldNames.isReserved(name)) {
|
|
1224
|
-
console.warn(`@org-quicko/silo-client: collection schema declares reserved field "${name}", which the server never returns`);
|
|
1225
|
-
}
|
|
1226
|
-
}
|
|
1227
|
-
}
|
|
1228
1108
|
}
|
|
1229
1109
|
|
|
1230
1110
|
// src/variables/environment-variables.ts
|
|
@@ -2007,8 +1887,6 @@ export {
|
|
|
2007
1887
|
Search,
|
|
2008
1888
|
RowStream,
|
|
2009
1889
|
RouteInventory,
|
|
2010
|
-
ResolvedEntry,
|
|
2011
|
-
ReservedFieldNames,
|
|
2012
1890
|
RequestAbortedError,
|
|
2013
1891
|
RenameReport,
|
|
2014
1892
|
Projects,
|
|
@@ -2044,8 +1922,6 @@ export {
|
|
|
2044
1922
|
EntryReader,
|
|
2045
1923
|
EntryPageStream,
|
|
2046
1924
|
EntryPage,
|
|
2047
|
-
EntryBase,
|
|
2048
|
-
Entry,
|
|
2049
1925
|
ConflictError,
|
|
2050
1926
|
Collections,
|
|
2051
1927
|
CollectionSchema,
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Entry } from "../entries/entry.cjs";
|
|
2
2
|
import type { SearchSnippet } from "./search-snippet.cjs";
|
|
3
3
|
/**
|
|
4
4
|
* One result. The location sits on the hit rather than on the entry, which is
|
|
5
5
|
* what lets a caller link to a result found outside the scope on screen, and
|
|
6
6
|
* `environment` is mapped from the wire's `env`.
|
|
7
7
|
*
|
|
8
|
-
* The entry is
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* The entry is untyped: a result is not addressed to one collection, so there
|
|
9
|
+
* is no `Fields` to give it. Its `{{NAME}}` templates are resolved, so read it
|
|
10
|
+
* again through `collection.get(id, { variables: "raw" })` before editing.
|
|
11
11
|
*/
|
|
12
12
|
export interface SearchHit {
|
|
13
13
|
readonly project: string;
|
|
14
14
|
readonly environment: string;
|
|
15
15
|
readonly collection: string;
|
|
16
|
-
readonly entry:
|
|
16
|
+
readonly entry: Entry;
|
|
17
17
|
readonly snippets: readonly SearchSnippet[];
|
|
18
18
|
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Entry } from "../entries/entry.js";
|
|
2
2
|
import type { SearchSnippet } from "./search-snippet.js";
|
|
3
3
|
/**
|
|
4
4
|
* One result. The location sits on the hit rather than on the entry, which is
|
|
5
5
|
* what lets a caller link to a result found outside the scope on screen, and
|
|
6
6
|
* `environment` is mapped from the wire's `env`.
|
|
7
7
|
*
|
|
8
|
-
* The entry is
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* The entry is untyped: a result is not addressed to one collection, so there
|
|
9
|
+
* is no `Fields` to give it. Its `{{NAME}}` templates are resolved, so read it
|
|
10
|
+
* again through `collection.get(id, { variables: "raw" })` before editing.
|
|
11
11
|
*/
|
|
12
12
|
export interface SearchHit {
|
|
13
13
|
readonly project: string;
|
|
14
14
|
readonly environment: string;
|
|
15
15
|
readonly collection: string;
|
|
16
|
-
readonly entry:
|
|
16
|
+
readonly entry: Entry;
|
|
17
17
|
readonly snippets: readonly SearchSnippet[];
|
|
18
18
|
}
|
package/dist/search/search.d.cts
CHANGED
|
@@ -14,5 +14,8 @@ export declare class Search {
|
|
|
14
14
|
private readonly reach;
|
|
15
15
|
constructor(transport: Transport, reach: SearchReach);
|
|
16
16
|
run(query: SearchQuery, options?: RequestOptions): Promise<SearchPage>;
|
|
17
|
-
|
|
17
|
+
/** `env` is the only rename: the hit's own location, which sits here rather
|
|
18
|
+
* than on the entry so a result found outside the scope on screen can still
|
|
19
|
+
* be linked to. */
|
|
20
|
+
private static toHit;
|
|
18
21
|
}
|
package/dist/search/search.d.ts
CHANGED
|
@@ -14,5 +14,8 @@ export declare class Search {
|
|
|
14
14
|
private readonly reach;
|
|
15
15
|
constructor(transport: Transport, reach: SearchReach);
|
|
16
16
|
run(query: SearchQuery, options?: RequestOptions): Promise<SearchPage>;
|
|
17
|
-
|
|
17
|
+
/** `env` is the only rename: the hit's own location, which sits here rather
|
|
18
|
+
* than on the entry so a result found outside the scope on screen can still
|
|
19
|
+
* be linked to. */
|
|
20
|
+
private static toHit;
|
|
18
21
|
}
|
package/package.json
CHANGED
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@org-quicko/silo-client",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "A typed, object-oriented client for silo's HTTP API",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"silo",
|
|
7
|
-
"cms",
|
|
8
|
-
"headless-cms",
|
|
9
|
-
"client",
|
|
10
|
-
"api"
|
|
11
|
-
],
|
|
12
|
-
"homepage": "https://github.com/org-quicko/silo#silo-client",
|
|
13
|
-
"repository": {
|
|
14
|
-
"type": "git",
|
|
15
|
-
"url": "git+https://github.com/org-quicko/silo.git",
|
|
16
|
-
"directory": "packages/silo-client"
|
|
17
|
-
},
|
|
18
|
-
"license": "AGPL-3.0-or-later",
|
|
19
|
-
"type": "module",
|
|
20
|
-
"exports": {
|
|
21
|
-
".": {
|
|
22
|
-
"import": {
|
|
23
|
-
"types": "./dist/index.d.ts",
|
|
24
|
-
"default": "./dist/index.js"
|
|
25
|
-
},
|
|
26
|
-
"require": {
|
|
27
|
-
"types": "./dist/index.d.cts",
|
|
28
|
-
"default": "./dist/index.cjs"
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
"main": "./dist/index.cjs",
|
|
33
|
-
"module": "./dist/index.js",
|
|
34
|
-
"types": "./dist/index.d.ts",
|
|
35
|
-
"files": [
|
|
36
|
-
"dist",
|
|
37
|
-
"README.md"
|
|
38
|
-
],
|
|
39
|
-
"engines": {
|
|
40
|
-
"node": ">=18"
|
|
41
|
-
},
|
|
42
|
-
"scripts": {
|
|
43
|
-
"build": "bun run build:esm && bun run build:cjs && bun run build:types",
|
|
44
|
-
"build:esm": "bun build src/index.ts --format=esm --outfile dist/index.js",
|
|
45
|
-
"build:cjs": "bun build src/index.ts --format=cjs --outfile dist/index.cjs",
|
|
46
|
-
"build:types": "tsc -p tsconfig.build.json && bun run tools/emit-cts-types.ts",
|
|
47
|
-
"test": "bun test",
|
|
48
|
-
"test:packaged": "bun run tools/packaged-tests.ts",
|
|
49
|
-
"typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.test.json",
|
|
50
|
-
"prepublishOnly": "bun run build"
|
|
51
|
-
},
|
|
52
|
-
"devDependencies": {
|
|
53
|
-
"@arethetypeswrong/cli": "^0.18.
|
|
54
|
-
"@silo/shared": "workspace:*",
|
|
55
|
-
"publint": "^0.3.
|
|
56
|
-
"typescript": "^7.0.2"
|
|
57
|
-
}
|
|
58
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@org-quicko/silo-client",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "A typed, object-oriented client for silo's HTTP API",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"silo",
|
|
7
|
+
"cms",
|
|
8
|
+
"headless-cms",
|
|
9
|
+
"client",
|
|
10
|
+
"api"
|
|
11
|
+
],
|
|
12
|
+
"homepage": "https://github.com/org-quicko/silo#silo-client",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/org-quicko/silo.git",
|
|
16
|
+
"directory": "packages/silo-client"
|
|
17
|
+
},
|
|
18
|
+
"license": "AGPL-3.0-or-later",
|
|
19
|
+
"type": "module",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"import": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"default": "./dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"require": {
|
|
27
|
+
"types": "./dist/index.d.cts",
|
|
28
|
+
"default": "./dist/index.cjs"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"main": "./dist/index.cjs",
|
|
33
|
+
"module": "./dist/index.js",
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"README.md"
|
|
38
|
+
],
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "bun run build:esm && bun run build:cjs && bun run build:types",
|
|
44
|
+
"build:esm": "bun build src/index.ts --format=esm --outfile dist/index.js",
|
|
45
|
+
"build:cjs": "bun build src/index.ts --format=cjs --outfile dist/index.cjs",
|
|
46
|
+
"build:types": "tsc -p tsconfig.build.json && bun run tools/emit-cts-types.ts",
|
|
47
|
+
"test": "bun test",
|
|
48
|
+
"test:packaged": "bun run tools/packaged-tests.ts",
|
|
49
|
+
"typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.test.json",
|
|
50
|
+
"prepublishOnly": "bun run build"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@arethetypeswrong/cli": "^0.18.5",
|
|
54
|
+
"@silo/shared": "workspace:*",
|
|
55
|
+
"publint": "^0.3.24",
|
|
56
|
+
"typescript": "^7.0.2"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The five field names the server strips from every entry response before
|
|
3
|
-
* answering, verified against `EntryUtils.toApiResponse`. A schema
|
|
4
|
-
* declaring one still validates and stores it; it just never comes back.
|
|
5
|
-
*/
|
|
6
|
-
export declare class ReservedFieldNames {
|
|
7
|
-
static readonly all: readonly string[];
|
|
8
|
-
static isReserved(name: string): boolean;
|
|
9
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The five field names the server strips from every entry response before
|
|
3
|
-
* answering, verified against `EntryUtils.toApiResponse`. A schema
|
|
4
|
-
* declaring one still validates and stores it; it just never comes back.
|
|
5
|
-
*/
|
|
6
|
-
export declare class ReservedFieldNames {
|
|
7
|
-
static readonly all: readonly string[];
|
|
8
|
-
static isReserved(name: string): boolean;
|
|
9
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import type { RequestOptions } from "../request-options.cjs";
|
|
2
|
-
import type { Transport } from "../transport/transport.cjs";
|
|
3
|
-
import type { EntryPayload } from "./entry-payload.cjs";
|
|
4
|
-
/** What an entry needs to address itself: the transport, and the scope and
|
|
5
|
-
* collection its id lives in. */
|
|
6
|
-
export interface EntryContext {
|
|
7
|
-
readonly transport: Transport;
|
|
8
|
-
readonly project: string;
|
|
9
|
-
readonly environment: string;
|
|
10
|
-
readonly collection: string;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* What every entry has regardless of whether it is editable: identity,
|
|
14
|
-
* timestamps, its fields, a plain snapshot, and `delete()` — which needs
|
|
15
|
-
* only an id and a rev, not the content. `rev`/`createdAt`/`updatedAt`/
|
|
16
|
-
* `fields` are declared `readonly` here; {@link Entry} is the one subclass
|
|
17
|
-
* that redeclares them mutable, since it is the one subclass with something
|
|
18
|
-
* that legitimately changes them.
|
|
19
|
-
*/
|
|
20
|
-
export declare abstract class EntryBase<Fields> {
|
|
21
|
-
protected readonly context: EntryContext;
|
|
22
|
-
readonly id: string;
|
|
23
|
-
readonly rev: number;
|
|
24
|
-
readonly createdAt: Date;
|
|
25
|
-
readonly updatedAt: Date;
|
|
26
|
-
readonly fields: Fields;
|
|
27
|
-
constructor(context: EntryContext, payload: EntryPayload);
|
|
28
|
-
/** The flat wire shape, for logging or React state. */
|
|
29
|
-
toJSON(): EntryPayload;
|
|
30
|
-
delete(options?: RequestOptions): Promise<void>;
|
|
31
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import type { RequestOptions } from "../request-options.js";
|
|
2
|
-
import type { Transport } from "../transport/transport.js";
|
|
3
|
-
import type { EntryPayload } from "./entry-payload.js";
|
|
4
|
-
/** What an entry needs to address itself: the transport, and the scope and
|
|
5
|
-
* collection its id lives in. */
|
|
6
|
-
export interface EntryContext {
|
|
7
|
-
readonly transport: Transport;
|
|
8
|
-
readonly project: string;
|
|
9
|
-
readonly environment: string;
|
|
10
|
-
readonly collection: string;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* What every entry has regardless of whether it is editable: identity,
|
|
14
|
-
* timestamps, its fields, a plain snapshot, and `delete()` — which needs
|
|
15
|
-
* only an id and a rev, not the content. `rev`/`createdAt`/`updatedAt`/
|
|
16
|
-
* `fields` are declared `readonly` here; {@link Entry} is the one subclass
|
|
17
|
-
* that redeclares them mutable, since it is the one subclass with something
|
|
18
|
-
* that legitimately changes them.
|
|
19
|
-
*/
|
|
20
|
-
export declare abstract class EntryBase<Fields> {
|
|
21
|
-
protected readonly context: EntryContext;
|
|
22
|
-
readonly id: string;
|
|
23
|
-
readonly rev: number;
|
|
24
|
-
readonly createdAt: Date;
|
|
25
|
-
readonly updatedAt: Date;
|
|
26
|
-
readonly fields: Fields;
|
|
27
|
-
constructor(context: EntryContext, payload: EntryPayload);
|
|
28
|
-
/** The flat wire shape, for logging or React state. */
|
|
29
|
-
toJSON(): EntryPayload;
|
|
30
|
-
delete(options?: RequestOptions): Promise<void>;
|
|
31
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { EntryPayload } from "./entry-payload.cjs";
|
|
2
|
-
/**
|
|
3
|
-
* The one place an entry's envelope (`id`, `rev`, `created_at`, `updated_at`)
|
|
4
|
-
* is split from its content. Never touches a field name either direction
|
|
5
|
-
*: whatever is left after the four known keys are removed is handed
|
|
6
|
-
* back exactly as it arrived.
|
|
7
|
-
*/
|
|
8
|
-
export declare class EntryMapper {
|
|
9
|
-
static fieldsOf<Fields>(payload: EntryPayload): Fields;
|
|
10
|
-
/** The flat wire shape `toJSON()` answers: the envelope rebuilt around
|
|
11
|
-
* whatever `fields` currently holds. */
|
|
12
|
-
static toPayload<Fields>(id: string, rev: number, fields: Fields, createdAt: Date, updatedAt: Date): EntryPayload;
|
|
13
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { EntryPayload } from "./entry-payload.js";
|
|
2
|
-
/**
|
|
3
|
-
* The one place an entry's envelope (`id`, `rev`, `created_at`, `updated_at`)
|
|
4
|
-
* is split from its content. Never touches a field name either direction
|
|
5
|
-
*: whatever is left after the four known keys are removed is handed
|
|
6
|
-
* back exactly as it arrived.
|
|
7
|
-
*/
|
|
8
|
-
export declare class EntryMapper {
|
|
9
|
-
static fieldsOf<Fields>(payload: EntryPayload): Fields;
|
|
10
|
-
/** The flat wire shape `toJSON()` answers: the envelope rebuilt around
|
|
11
|
-
* whatever `fields` currently holds. */
|
|
12
|
-
static toPayload<Fields>(id: string, rev: number, fields: Fields, createdAt: Date, updatedAt: Date): EntryPayload;
|
|
13
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* One entry exactly as the wire answers it: flattened, with the user's
|
|
3
|
-
* fields alongside the four envelope keys. `EntryUtils.toApiResponse` is
|
|
4
|
-
* where the server builds this shape.
|
|
5
|
-
*/
|
|
6
|
-
export interface EntryPayload {
|
|
7
|
-
id: string;
|
|
8
|
-
rev: number;
|
|
9
|
-
created_at: string;
|
|
10
|
-
updated_at: string;
|
|
11
|
-
[field: string]: unknown;
|
|
12
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* One entry exactly as the wire answers it: flattened, with the user's
|
|
3
|
-
* fields alongside the four envelope keys. `EntryUtils.toApiResponse` is
|
|
4
|
-
* where the server builds this shape.
|
|
5
|
-
*/
|
|
6
|
-
export interface EntryPayload {
|
|
7
|
-
id: string;
|
|
8
|
-
rev: number;
|
|
9
|
-
created_at: string;
|
|
10
|
-
updated_at: string;
|
|
11
|
-
[field: string]: unknown;
|
|
12
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { EntryBase } from "./entry-base.cjs";
|
|
2
|
-
/**
|
|
3
|
-
* A read whose variables have been substituted. Adds nothing over
|
|
4
|
-
* {@link EntryBase}: no `save()`, no `refresh()` — writing a resolved value
|
|
5
|
-
* back would overwrite whatever `{{NAME}}` template produced it. `fields` is
|
|
6
|
-
* narrowed to `Readonly<Fields>` at the type level; `Entry` is what an
|
|
7
|
-
* editor asks for instead.
|
|
8
|
-
*/
|
|
9
|
-
export declare class ResolvedEntry<Fields> extends EntryBase<Fields> {
|
|
10
|
-
readonly fields: Readonly<Fields>;
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { EntryBase } from "./entry-base.js";
|
|
2
|
-
/**
|
|
3
|
-
* A read whose variables have been substituted. Adds nothing over
|
|
4
|
-
* {@link EntryBase}: no `save()`, no `refresh()` — writing a resolved value
|
|
5
|
-
* back would overwrite whatever `{{NAME}}` template produced it. `fields` is
|
|
6
|
-
* narrowed to `Readonly<Fields>` at the type level; `Entry` is what an
|
|
7
|
-
* editor asks for instead.
|
|
8
|
-
*/
|
|
9
|
-
export declare class ResolvedEntry<Fields> extends EntryBase<Fields> {
|
|
10
|
-
readonly fields: Readonly<Fields>;
|
|
11
|
-
}
|