@@ -139,5 +139,236 @@ <h4>Storage Description Representation</h4>
139139}
140140 </ pre >
141141 </ section >
142+
142143</ section >
143144
145+ < section id ="type-index-service ">
146+ < h3 > TypeIndexService</ h3 >
147+ < p > A server advertising in < code > storageDescription</ code > :</ p >
148+ < pre class ="example " title ="TypeIndexService advertised in storage description ">
149+ {
150+ "@context": "https://www.w3.org/ns/lws/v1",
151+ "type": "Storage",
152+ "service": [
153+ {
154+ "type": "TypeIndexService",
155+ "serviceEndpoint": "https://example.org/types/index"
156+ }
157+ ]
158+ }
159+ </ pre >
160+ < p > A server that implements this MUST advertise the service in the storage description resource.</ p >
161+
162+ < section >
163+ < h4 > GET [serviceEndpoint]</ h4 >
164+ < p > Returns < code > application/lws+json</ code > :</ p >
165+ < pre class ="example ">
166+ {
167+ "@context": "https://www.w3.org/ns/lws/v1",
168+ "type": "TypeIndex",
169+ "searchEndpoint": "https://example.org/types/search",
170+ "totalItems": 55,
171+ "items": [
172+ {
173+ "type": "https://schema.org/Person",
174+ "default": "https://example.org/data/people/",
175+ "location": ["https://example.org/data/people/"]
176+ },
177+ {
178+ "type": "https://schema.org/Event",
179+ "default": "https://example.org/data/events/",
180+ "location": [
181+ "https://example.org/data/events/",
182+ "https://example.org/data/calendar/"]
183+ }
184+ ],
185+ "next": "..."
186+ }
187+ </ pre >
188+ < p > < code > searchEndpoint</ code > REQUIRED. < code > default</ code > OPTIONAL. < code > location</ code > array of container URIs (always an array).</ p >
189+ < p > Supports query parameters (all optional): < code > ?type=<URI></ code > (repeatable, AND), < code > ?filter[<propURI>]=<value></ code > (repeatable, AND), < code > ?fields=type,default,location</ code > .</ p >
190+ < p class ="note "> Clients MUST URL-encode query parameter keys/values.</ p >
191+ < p > Returns paginated TypeIndex following LWS pagination. No other parameters.</ p >
192+ </ section >
193+
194+ < section >
195+ < h4 > POST [serviceEndpoint]</ h4 >
196+ < p > MUST support < code > application/lws+json</ code > body:</ p >
197+ < pre class ="example ">
198+ {
199+ "@context": "https://www.w3.org/ns/lws/v1"
200+ }
201+ </ pre >
202+ < p > Returns everything in the type index (same as GET).</ p >
203+ < p > Optional filters: < code > type</ code > array of URIs (AND), top-level property-URI keys = filters (AND).</ p >
204+ < p > Returns paginated TypeIndex of matching entries. No other params.</ p >
205+ </ section >
206+
207+ < section >
208+ < h4 > GET [searchEndpoint]</ h4 >
209+ < p > Supports same query params as GET [serviceEndpoint] except < code > fields</ code > .</ p >
210+ < p > Returns < code > application/lws+json</ code > : paginated ContainerPage of matching LWS Resource URIs. No other params.</ p >
211+ </ section >
212+
213+ < section >
214+ < h4 > POST [searchEndpoint]</ h4 >
215+ < p > MUST support < code > application/lws+json</ code > body:</ p >
216+ < pre class ="example ">
217+ {
218+ "@context": "https://www.w3.org/ns/lws/v1",
219+ "type": ["https://schema.org/Person"]
220+ }
221+ </ pre >
222+ < p > < code > type</ code > : array of URIs (AND). Top-level property-URI keys = filters (AND).</ p >
223+ < p > Returns paginated ContainerPage of matching LWS Resource URIs. No other parameters.</ p >
224+ </ section >
225+
226+ < section >
227+ < h4 > Security</ h4 >
228+ < p > Servers MUST enforce authorization per access grants. Responses to GET/POST on < code > TypeIndexService</ code > or < code > searchEndpoint</ code > include only types, defaults, locations, and resource URIs the authenticated client may read (via grants). Unauthorized entries omitted. Grant listing implicitly yields a client-specific type index.</ p >
229+ </ section >
230+
231+ < section >
232+ < h4 > Non-Normative Examples</ h4 >
233+
234+ < pre class ="example " title ="Example 1: GET TypeIndex ">
235+ Request
236+ GET /types/index
237+ Response
238+ {
239+ "@context": "https://www.w3.org/ns/lws/v1",
240+ "type": "TypeIndex",
241+ "searchEndpoint": "https://example.org/types/search",
242+ "totalItems": 55,
243+ "items": [
244+ {
245+ "type": "https://schema.org/Person",
246+ "default": "https://example.org/data/people/",
247+ "location": ["https://example.org/data/people/"]
248+ },
249+ {
250+ "type": "https://schema.org/Event",
251+ "default": "https://example.org/data/events/",
252+ "location": [
253+ "https://example.org/data/events/",
254+ "https://example.org/data/calendar/"]
255+ }
256+ ],
257+ "next": "https://example.org/types/index?page=2"
258+ }
259+ </ pre >
260+
261+ < pre class ="example " title ="Example 2: GET TypeIndex with filter ">
262+ Request
263+ GET /types/index?type=https%3A%2F%2Fschema.org%2FEvent&fields=type,default
264+ Response
265+ {
266+ "@context": "https://www.w3.org/ns/lws/v1",
267+ "type": "TypeIndex",
268+ "searchEndpoint": "https://example.org/types/search",
269+ "totalItems": 8,
270+ "items": [{ "type": "https://schema.org/Event", "default": "https://example.org/data/events/" }],
271+ "next": "https://example.org/types/index?type=https%3A%2F%2Fschema.org%2FEvent&fields=type,default&page=2"
272+ }
273+ </ pre >
274+
275+ < pre class ="example " title ="Example 3: POST TypeIndex with filters ">
276+ Request
277+ POST /types/index
278+ Request Body
279+ {
280+ "@context": "https://www.w3.org/ns/lws/v1",
281+ "type": ["https://schema.org/Person"]
282+ }
283+ Response
284+ {
285+ "@context": "https://www.w3.org/ns/lws/v1",
286+ "type": "TypeIndex",
287+ "searchEndpoint": "https://example.org/types/search",
288+ "totalItems": 27,
289+ "items": [{ "type": "https://schema.org/Person" }],
290+ "next": "https://example.org/types/index?page=2"
291+ }
292+ </ pre >
293+
294+ < pre class ="example " title ="Example 4: Simple GET search ">
295+ Request
296+ GET /types/search?type=https%3A%2F%2Fschema.org%2FPerson
297+ Response
298+ {
299+ "@context": "https://www.w3.org/ns/lws/v1",
300+ "type": "ContainerPage",
301+ "totalItems": 27,
302+ "items": [
303+ "https://example.org/data/person-4872",
304+ "https://example.org/data/person-4873",
305+ "https://example.org/data/person-5882",
306+ "https://example.org/data/person-1877",
307+ "https://example.org/data/person-9341"
308+ ],
309+ "next": "https://example.org/types/search?type=https%3A%2F%2Fschema.org%2FPerson&page=2"
310+ }
311+ </ pre >
312+
313+ < pre class ="example " title ="Example 5: GET with filter ">
314+ Request
315+ GET /types/search?filter[https://schema.org/location]=https://example.org/venue
316+ Response
317+ {
318+ "@context": "https://www.w3.org/ns/lws/v1",
319+ "type": "ContainerPage",
320+ "totalItems": 4,
321+ "items": [
322+ "https://example.org/data/event-123",
323+ "https://example.org/data/event-456"
324+ ],
325+ "next": "https://example.org/types/search?filter[https%3A%2F%2Fschema.org%2Flocation]=https%3A%2F%2Fexample.org%2Fvenue&page=2"
326+ }
327+ </ pre >
328+
329+ < pre class ="example " title ="Example 6: POST search with filters ">
330+ Request
331+ POST /types/search
332+ Request Body
333+ {
334+ "@context": "https://www.w3.org/ns/lws/v1",
335+ "type": ["https://schema.org/Person"],
336+ "https://schema.org/worksFor": "https://example.org/companies/acme-inc"
337+ }
338+ Response
339+ {
340+ "@context": "https://www.w3.org/ns/lws/v1",
341+ "type": "ContainerPage",
342+ "totalItems": 3,
343+ "items": [
344+ "https://example.org/data/person-4872",
345+ "https://example.org/data/person-9341",
346+ "https://example.org/data/person-1123"
347+ ]
348+ }
349+ </ pre >
350+
351+ < pre class ="example " title ="Example 7: POST with multiple filters ">
352+ Request
353+ POST /types/search
354+ Request Body
355+ {
356+ "@context": "https://www.w3.org/ns/lws/v1",
357+ "type": ["https://schema.org/Event"],
358+ "https://schema.org/location": "https://example.org/venue"
359+ }
360+ Response
361+ {
362+ "@context": "https://www.w3.org/ns/lws/v1",
363+ "type": "ContainerPage",
364+ "totalItems": 2,
365+ "items": [
366+ "https://example.org/data/event-8821",
367+ "https://example.org/data/event-9014"
368+ ],
369+ "next": "https://example.org/types/search?page=2"
370+ }
371+ </ pre >
372+ </ section >
373+ </ section >
374+
0 commit comments