@undefineds.co/xpod 0.3.56 → 0.3.58
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/api/container/index.js +3 -0
- package/dist/api/container/index.js.map +1 -1
- package/dist/api/container/local.js +53 -13
- package/dist/api/container/local.js.map +1 -1
- package/dist/api/container/types.d.ts +6 -0
- package/dist/api/container/types.js.map +1 -1
- package/dist/api/handlers/AdminHandler.d.ts +15 -0
- package/dist/api/handlers/AdminHandler.js +128 -7
- package/dist/api/handlers/AdminHandler.js.map +1 -1
- package/dist/cli/commands/obj.d.ts +45 -0
- package/dist/cli/commands/obj.js +309 -33
- package/dist/cli/commands/obj.js.map +1 -1
- package/dist/components/components.jsonld +1 -0
- package/dist/components/context.jsonld +36 -0
- package/dist/edge/DdnsManager.d.ts +1 -1
- package/dist/edge/DdnsManager.js.map +1 -1
- package/dist/edge/reachability/P2PRealnetAcceptance.js +4 -3
- package/dist/edge/reachability/P2PRealnetAcceptance.js.map +1 -1
- package/dist/edge/reachability/TcpP2PSignalingSession.js +26 -17
- package/dist/edge/reachability/TcpP2PSignalingSession.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/tunnel/NgrokTunnelProvider.d.ts +46 -0
- package/dist/tunnel/NgrokTunnelProvider.js +344 -0
- package/dist/tunnel/NgrokTunnelProvider.js.map +1 -0
- package/dist/tunnel/NgrokTunnelProvider.jsonld +215 -0
- package/dist/tunnel/TunnelProvider.d.ts +2 -2
- package/dist/tunnel/TunnelProvider.js.map +1 -1
- package/dist/tunnel/index.d.ts +1 -0
- package/dist/tunnel/index.js +3 -1
- package/dist/tunnel/index.js.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-database.d.ts +62 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-database.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-database.js +197 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-database.js.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-database.d.ts +62 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-database.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-database.js +197 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-database.js.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/pod.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/pod.d.ts.map +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/package.json +1 -1
- package/package.json +10 -6
- package/static/app/assets/{index-AaQ1qxhy.js → index-C1yksyT4.js} +28 -28
- package/static/app/assets/inrupt-smoke.js +2 -2
- package/static/app/assets/main.css +1 -1
- package/static/app/assets/main.js +10 -50
- package/static/dashboard/assets/dashboard-BssaVKTn.css +1 -0
- package/static/dashboard/assets/dashboard-Ckuadl3C.js +54 -0
- package/static/dashboard/dashboard.html +2 -2
- package/static/dashboard/reachability.html +221 -0
- package/static/dashboard/reachability.svg +7 -0
- package/static/dashboard/reachability.webmanifest +18 -0
- package/static/dashboard/signal-pod.html +293 -0
- package/static/dashboard/assets/dashboard-CTk9cn1-.js +0 -52
- package/static/dashboard/assets/dashboard-VQRsvXx9.css +0 -1
package/dist/cli/commands/obj.js
CHANGED
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.objCommand = void 0;
|
|
4
|
+
exports.resolveObjMutationContext = resolveObjMutationContext;
|
|
5
|
+
exports.getObjLocalOutboxPath = getObjLocalOutboxPath;
|
|
4
6
|
exports.redactDescriptorObject = redactDescriptorObject;
|
|
7
|
+
exports.serializeSchemaDescriptor = serializeSchemaDescriptor;
|
|
8
|
+
exports.listSchemaDescriptors = listSchemaDescriptors;
|
|
9
|
+
exports.describeSchemaDescriptor = describeSchemaDescriptor;
|
|
5
10
|
exports.buildDescriptorUpsertSparql = buildDescriptorUpsertSparql;
|
|
6
11
|
exports.buildDescriptorPatchSparql = buildDescriptorPatchSparql;
|
|
7
12
|
exports.buildDescriptorLinkSparql = buildDescriptorLinkSparql;
|
|
8
13
|
exports.buildDescriptorDeleteSparql = buildDescriptorDeleteSparql;
|
|
9
14
|
exports.extractReservedWhereSelectors = extractReservedWhereSelectors;
|
|
10
15
|
exports.buildDescriptorObjectQuery = buildDescriptorObjectQuery;
|
|
16
|
+
exports.descriptorObjectFromTurtle = descriptorObjectFromTurtle;
|
|
17
|
+
exports.descriptorUpsertPlanItem = descriptorUpsertPlanItem;
|
|
18
|
+
exports.executeRows = executeRows;
|
|
19
|
+
exports.mutationItemsResultCode = mutationItemsResultCode;
|
|
11
20
|
const fs_1 = require("fs");
|
|
21
|
+
const path_1 = require("path");
|
|
22
|
+
const n3_1 = require("n3");
|
|
12
23
|
const models_1 = require("@undefineds.co/models");
|
|
13
24
|
const auth_context_1 = require("../lib/auth-context");
|
|
25
|
+
const credentials_store_1 = require("../lib/credentials-store");
|
|
14
26
|
const output_1 = require("../lib/output");
|
|
15
27
|
const resource_1 = require("../lib/resource");
|
|
16
28
|
const rdf_1 = require("./rdf");
|
|
@@ -93,14 +105,28 @@ async function readJsonl(input) {
|
|
|
93
105
|
function descriptorLocalName(value) {
|
|
94
106
|
return value.split(/[\/#]/u).filter(Boolean).pop() ?? value;
|
|
95
107
|
}
|
|
108
|
+
function normalizeDescriptorAlias(value) {
|
|
109
|
+
return value.toLowerCase().replace(/[^a-z0-9]+/gu, '');
|
|
110
|
+
}
|
|
111
|
+
function descriptorAliases(descriptor) {
|
|
112
|
+
const discovery = descriptor;
|
|
113
|
+
return discovery.aliases?.length ? discovery.aliases : [descriptorLocalName(descriptor.class)];
|
|
114
|
+
}
|
|
115
|
+
function descriptorMatchesRef(descriptor, ref) {
|
|
116
|
+
const normalized = normalizeDescriptorAlias(ref);
|
|
117
|
+
return descriptor.uri === ref ||
|
|
118
|
+
descriptor.class === ref ||
|
|
119
|
+
descriptor.resourceKind.toLowerCase() === ref.trim().toLowerCase() ||
|
|
120
|
+
normalizeDescriptorAlias(descriptorLocalName(descriptor.uri)) === normalized ||
|
|
121
|
+
normalizeDescriptorAlias(descriptorLocalName(descriptor.class)) === normalized ||
|
|
122
|
+
descriptorAliases(descriptor).some((alias) => normalizeDescriptorAlias(alias) === normalized);
|
|
123
|
+
}
|
|
96
124
|
function resolveDescriptorOrNull(schema) {
|
|
97
|
-
const exact = models_1.podSchema.describe({ schemaUri: schema })
|
|
125
|
+
const exact = models_1.podSchema.describe({ schemaUri: schema }) ??
|
|
126
|
+
models_1.podSchema.describe?.({ alias: schema });
|
|
98
127
|
if (exact)
|
|
99
128
|
return exact;
|
|
100
|
-
|
|
101
|
-
return models_1.podSchema.list().find((descriptor) => descriptor.resourceKind.toLowerCase() === normalized ||
|
|
102
|
-
descriptorLocalName(descriptor.uri).toLowerCase() === normalized ||
|
|
103
|
-
descriptorLocalName(descriptor.class).toLowerCase() === normalized) ?? null;
|
|
129
|
+
return models_1.podSchema.list().find((descriptor) => descriptorMatchesRef(descriptor, schema)) ?? null;
|
|
104
130
|
}
|
|
105
131
|
function resolveDescriptor(schema) {
|
|
106
132
|
const descriptor = resolveDescriptorOrNull(schema);
|
|
@@ -112,6 +138,48 @@ function resolveDescriptor(schema) {
|
|
|
112
138
|
function resourceUrlFromPlan(podRoot, plan) {
|
|
113
139
|
return new URL(plan.resourceUri.replace(/^\/+/, ''), podRoot).toString();
|
|
114
140
|
}
|
|
141
|
+
async function resolveObjMutationContext(argv, commit) {
|
|
142
|
+
try {
|
|
143
|
+
return await (0, auth_context_1.requireAuthContext)(argv);
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
const podRoot = (0, auth_context_1.normalizeBaseUrl)(argv.url ?? 'https://pod.local/');
|
|
147
|
+
const outboxPath = getObjLocalOutboxPath();
|
|
148
|
+
return {
|
|
149
|
+
baseUrl: podRoot,
|
|
150
|
+
webId: 'urn:xpod:unauthenticated',
|
|
151
|
+
podRoot,
|
|
152
|
+
baseIri: podRoot,
|
|
153
|
+
accessToken: '',
|
|
154
|
+
credentials: {
|
|
155
|
+
url: podRoot,
|
|
156
|
+
webId: 'urn:xpod:unauthenticated',
|
|
157
|
+
authType: 'client_credentials',
|
|
158
|
+
secrets: {
|
|
159
|
+
clientId: '',
|
|
160
|
+
clientSecret: '',
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
...(commit
|
|
164
|
+
? {
|
|
165
|
+
pendingOnly: true,
|
|
166
|
+
outboxPath,
|
|
167
|
+
pendingWarning: `No Solid credentials found; mutation was written to local xpod outbox at ${outboxPath} and was not saved to a Pod.`,
|
|
168
|
+
}
|
|
169
|
+
: {
|
|
170
|
+
planningOnly: true,
|
|
171
|
+
planningWarning: 'No Solid credentials found; this is an offline dry-run plan and was not saved to a Pod.',
|
|
172
|
+
}),
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function getObjLocalOutboxPath() {
|
|
177
|
+
return (0, path_1.join)((0, credentials_store_1.getSolidHomeDir)(), 'apps', 'xpod', 'outbox', 'obj-mutations.jsonl');
|
|
178
|
+
}
|
|
179
|
+
function appendObjLocalOutbox(entry, outboxPath = getObjLocalOutboxPath()) {
|
|
180
|
+
(0, fs_1.mkdirSync)((0, path_1.dirname)(outboxPath), { recursive: true });
|
|
181
|
+
(0, fs_1.appendFileSync)(outboxPath, `${JSON.stringify(entry)}\n`, 'utf-8');
|
|
182
|
+
}
|
|
115
183
|
function varName(field) {
|
|
116
184
|
return `v_${field.replace(/[^A-Za-z0-9_]/gu, '_')}`;
|
|
117
185
|
}
|
|
@@ -159,6 +227,47 @@ function redactDescriptorObject(descriptor, value) {
|
|
|
159
227
|
}
|
|
160
228
|
return redacted;
|
|
161
229
|
}
|
|
230
|
+
function serializeSchemaDescriptor(descriptor) {
|
|
231
|
+
const discovery = descriptor;
|
|
232
|
+
return {
|
|
233
|
+
schema: descriptor.uri,
|
|
234
|
+
uri: descriptor.uri,
|
|
235
|
+
alias: descriptorAliases(descriptor)[0] ?? descriptor.resourceKind,
|
|
236
|
+
aliases: descriptorAliases(descriptor),
|
|
237
|
+
domains: discovery.domains ?? [],
|
|
238
|
+
version: descriptor.version,
|
|
239
|
+
source: descriptor.source,
|
|
240
|
+
trustLevel: descriptor.trustLevel,
|
|
241
|
+
namespace: descriptor.namespace,
|
|
242
|
+
class: descriptor.class,
|
|
243
|
+
resourceKind: descriptor.resourceKind,
|
|
244
|
+
description: descriptor.description,
|
|
245
|
+
storage: descriptor.storage,
|
|
246
|
+
idSemantics: discovery.idSemantics ?? null,
|
|
247
|
+
relationFields: discovery.relationFields ?? Object.entries(descriptor.fields)
|
|
248
|
+
.filter(([, field]) => field.type === 'uri')
|
|
249
|
+
.map(([field]) => field),
|
|
250
|
+
documentPathPolicy: discovery.documentPathPolicy ?? null,
|
|
251
|
+
fields: descriptor.fields,
|
|
252
|
+
requiredFields: Object.entries(descriptor.fields)
|
|
253
|
+
.filter(([, field]) => field.required)
|
|
254
|
+
.map(([field]) => field),
|
|
255
|
+
uniqueBy: descriptor.uniqueBy,
|
|
256
|
+
writableFields: descriptor.writableFields,
|
|
257
|
+
mergePolicy: descriptor.mergePolicy,
|
|
258
|
+
exampleInput: discovery.exampleInput ?? descriptor.examples[0] ?? null,
|
|
259
|
+
examples: descriptor.examples,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
function listSchemaDescriptors(input = {}, descriptors = models_1.podSchema.list()) {
|
|
263
|
+
return descriptors
|
|
264
|
+
.filter((descriptor) => !input.domain || (descriptor.domains ?? []).includes(input.domain))
|
|
265
|
+
.map(serializeSchemaDescriptor);
|
|
266
|
+
}
|
|
267
|
+
function describeSchemaDescriptor(schemaOrAlias, descriptors = models_1.podSchema.list()) {
|
|
268
|
+
const descriptor = descriptors.find((item) => descriptorMatchesRef(item, schemaOrAlias));
|
|
269
|
+
return descriptor ? serializeSchemaDescriptor(descriptor) : null;
|
|
270
|
+
}
|
|
162
271
|
function buildDescriptorUpsertSparql(descriptor, subject, row) {
|
|
163
272
|
const fields = descriptor.fields;
|
|
164
273
|
const match = row.match ?? {};
|
|
@@ -167,15 +276,17 @@ function buildDescriptorUpsertSparql(descriptor, subject, row) {
|
|
|
167
276
|
assertWritableFields(descriptor, set);
|
|
168
277
|
const merged = { ...match, ...set };
|
|
169
278
|
const deleteFields = Object.keys(set).filter((field) => fields[field]);
|
|
170
|
-
const deletes = deleteFields.map((field) =>
|
|
171
|
-
const optionals = deleteFields.map((field) => `OPTIONAL { <${subject}> <${fields[field].predicate}> ?old_${field.replace(/[^A-Za-z0-9_]/gu, '_')} }`);
|
|
279
|
+
const deletes = deleteFields.map((field) => `DELETE WHERE {\n <${subject}> <${fields[field].predicate}> ?old_${field.replace(/[^A-Za-z0-9_]/gu, '_')} .\n}`);
|
|
172
280
|
const inserts = [
|
|
173
281
|
`<${subject}> a <${descriptor.class}>`,
|
|
174
282
|
...Object.entries(merged)
|
|
175
283
|
.filter(([field, value]) => fields[field] && value !== undefined && value !== null)
|
|
176
284
|
.map(([field, value]) => `<${subject}> <${fields[field].predicate}> ${sparqlValue(value, fields[field])}`),
|
|
177
285
|
];
|
|
178
|
-
return
|
|
286
|
+
return [
|
|
287
|
+
...deletes,
|
|
288
|
+
`INSERT DATA {\n ${inserts.join(' .\n ')} .\n}`,
|
|
289
|
+
].join(';\n');
|
|
179
290
|
}
|
|
180
291
|
function buildDescriptorPatchSparql(descriptor, subject, set) {
|
|
181
292
|
return buildDescriptorUpsertSparql(descriptor, subject, { set });
|
|
@@ -382,6 +493,42 @@ function bindingToValue(binding, field) {
|
|
|
382
493
|
}
|
|
383
494
|
return binding.value;
|
|
384
495
|
}
|
|
496
|
+
function descriptorObjectFromTurtle(descriptor, subject, resourceUrl, turtle) {
|
|
497
|
+
const quads = new n3_1.Parser({ baseIRI: resourceUrl }).parse(turtle);
|
|
498
|
+
const object = {};
|
|
499
|
+
let hasDescriptorType = false;
|
|
500
|
+
for (const quad of quads) {
|
|
501
|
+
if (quad.subject.value !== subject)
|
|
502
|
+
continue;
|
|
503
|
+
if (quad.predicate.value === 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' &&
|
|
504
|
+
quad.object.value === descriptor.class) {
|
|
505
|
+
hasDescriptorType = true;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
for (const [field, descriptorField] of Object.entries(descriptor.fields)) {
|
|
509
|
+
const quad = quads.find((item) => item.subject.value === subject &&
|
|
510
|
+
item.predicate.value === descriptorField.predicate);
|
|
511
|
+
if (!quad)
|
|
512
|
+
continue;
|
|
513
|
+
const value = bindingToValue({
|
|
514
|
+
type: quad.object.termType === 'NamedNode' ? 'uri' : 'literal',
|
|
515
|
+
value: quad.object.value,
|
|
516
|
+
datatype: 'datatype' in quad.object ? quad.object.datatype.value : undefined,
|
|
517
|
+
}, descriptorField);
|
|
518
|
+
if (value !== undefined) {
|
|
519
|
+
object[field] = descriptorField.secret ? '[redacted]' : value;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
if (!hasDescriptorType && Object.keys(object).length === 0) {
|
|
523
|
+
return null;
|
|
524
|
+
}
|
|
525
|
+
return {
|
|
526
|
+
schema: descriptor.uri,
|
|
527
|
+
subject,
|
|
528
|
+
resourceUrl,
|
|
529
|
+
object,
|
|
530
|
+
};
|
|
531
|
+
}
|
|
385
532
|
async function applyEtags(context, objects) {
|
|
386
533
|
const cache = new Map();
|
|
387
534
|
for (const object of objects) {
|
|
@@ -417,6 +564,12 @@ async function queryDescriptorObjects(context, selector) {
|
|
|
417
564
|
},
|
|
418
565
|
body: query,
|
|
419
566
|
});
|
|
567
|
+
if (!response.ok) {
|
|
568
|
+
const fallback = await queryDescriptorObjectFromResource(context, selector);
|
|
569
|
+
if (fallback) {
|
|
570
|
+
return fallback;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
420
573
|
(0, resource_1.ensureOk)(response, 'obj_query_failed', `Failed to list objects for ${selector.descriptor.uri}`);
|
|
421
574
|
const result = (await response.json());
|
|
422
575
|
const objects = (result.results?.bindings ?? []).flatMap((binding) => {
|
|
@@ -442,6 +595,31 @@ async function queryDescriptorObjects(context, selector) {
|
|
|
442
595
|
}
|
|
443
596
|
return objects;
|
|
444
597
|
}
|
|
598
|
+
async function queryDescriptorObjectFromResource(context, selector) {
|
|
599
|
+
if (!selector.subject)
|
|
600
|
+
return null;
|
|
601
|
+
if (Object.keys(selector.where).length > 0)
|
|
602
|
+
return null;
|
|
603
|
+
if (Object.keys(selector.relations).length > 0)
|
|
604
|
+
return null;
|
|
605
|
+
const resourceUrl = (0, rdf_1.documentResourceInput)(selector.subject);
|
|
606
|
+
const target = (0, resource_1.resolveResourceTarget)(context, resourceUrl);
|
|
607
|
+
const response = await (0, resource_1.fetchResource)(context, target, {
|
|
608
|
+
method: 'GET',
|
|
609
|
+
headers: { Accept: 'text/turtle' },
|
|
610
|
+
});
|
|
611
|
+
if (response.status === 404)
|
|
612
|
+
return [];
|
|
613
|
+
if (!response.ok)
|
|
614
|
+
return null;
|
|
615
|
+
const turtle = await response.text();
|
|
616
|
+
const object = descriptorObjectFromTurtle(selector.descriptor, selector.subject, target.resourceUrl, turtle);
|
|
617
|
+
const objects = object ? [object] : [];
|
|
618
|
+
if (selector.includeMetadata) {
|
|
619
|
+
await applyEtags(context, objects);
|
|
620
|
+
}
|
|
621
|
+
return objects;
|
|
622
|
+
}
|
|
445
623
|
function jsonlForObjects(objects) {
|
|
446
624
|
return `${objects.map((object, index) => JSON.stringify({
|
|
447
625
|
index,
|
|
@@ -701,36 +879,51 @@ async function executeDescriptorRow(context, row, index, commit) {
|
|
|
701
879
|
}
|
|
702
880
|
throw new output_1.CliCommandError('unsupported_operation', `Unsupported object operation: ${op}`, 2);
|
|
703
881
|
}
|
|
704
|
-
const
|
|
882
|
+
const item = descriptorUpsertPlanItem({
|
|
883
|
+
descriptor,
|
|
884
|
+
index,
|
|
885
|
+
commit,
|
|
886
|
+
podRoot: context.podRoot,
|
|
887
|
+
row,
|
|
888
|
+
});
|
|
889
|
+
const subject = String(item.subject);
|
|
890
|
+
if (commit) {
|
|
891
|
+
const sparql = buildDescriptorUpsertSparql(descriptor, subject, row);
|
|
892
|
+
await patchSubject({ context, subject, sparql, ifMatch: row.ifMatch, errorCode: 'obj_commit_failed' });
|
|
893
|
+
}
|
|
894
|
+
return item;
|
|
895
|
+
}
|
|
896
|
+
function descriptorUpsertPlanItem(input) {
|
|
897
|
+
const storage = (0, models_1.createPodStorage)((0, models_1.createPodModelDescriptorRegistry)([input.descriptor]));
|
|
705
898
|
const validation = storage.validate({
|
|
706
|
-
schemaUri: descriptor.uri,
|
|
899
|
+
schemaUri: input.descriptor.uri,
|
|
707
900
|
operation: 'upsert',
|
|
708
|
-
match: row.match ?? {},
|
|
709
|
-
set: row.set ?? {},
|
|
901
|
+
match: input.row.match ?? {},
|
|
902
|
+
set: input.row.set ?? {},
|
|
710
903
|
});
|
|
711
904
|
if (!validation.ok) {
|
|
712
905
|
throw new output_1.CliCommandError(validation.error.code, validation.error.message, 2);
|
|
713
906
|
}
|
|
714
|
-
const
|
|
715
|
-
|
|
716
|
-
const sparql = buildDescriptorUpsertSparql(descriptor, subject, row);
|
|
717
|
-
await patchSubject({ context, subject, sparql, ifMatch: row.ifMatch, errorCode: 'obj_commit_failed' });
|
|
718
|
-
}
|
|
907
|
+
const discovery = input.descriptor;
|
|
908
|
+
const subject = resourceUrlFromPlan(input.podRoot, validation.plan);
|
|
719
909
|
return {
|
|
720
|
-
index,
|
|
910
|
+
index: input.index,
|
|
721
911
|
ok: true,
|
|
722
|
-
code: commit ? 'committed' : 'plan_ready',
|
|
723
|
-
operation: op,
|
|
724
|
-
schema: descriptor.uri,
|
|
912
|
+
code: input.commit ? 'committed' : 'plan_ready',
|
|
913
|
+
operation: input.row.op ?? 'upsert',
|
|
914
|
+
schema: input.descriptor.uri,
|
|
725
915
|
subject,
|
|
726
916
|
resourceUrl: (0, rdf_1.documentResourceInput)(subject),
|
|
727
917
|
planId: validation.plan.id,
|
|
728
|
-
|
|
729
|
-
|
|
918
|
+
resourceId: validation.plan.resourceId,
|
|
919
|
+
resourceUri: validation.plan.resourceUri,
|
|
920
|
+
documentPathPolicy: discovery.documentPathPolicy ?? null,
|
|
921
|
+
match: redactDescriptorObject(input.descriptor, input.row.match ?? {}),
|
|
922
|
+
set: redactDescriptorObject(input.descriptor, input.row.set ?? {}),
|
|
730
923
|
};
|
|
731
924
|
}
|
|
732
925
|
async function executeRows(input) {
|
|
733
|
-
const context = await (
|
|
926
|
+
const context = await resolveObjMutationContext(input.argv, input.commit);
|
|
734
927
|
const items = [];
|
|
735
928
|
for (const [index, originalRow] of input.rows.entries()) {
|
|
736
929
|
const row = {
|
|
@@ -738,10 +931,44 @@ async function executeRows(input) {
|
|
|
738
931
|
schema: originalRow.schema ?? input.defaultSchema,
|
|
739
932
|
};
|
|
740
933
|
try {
|
|
934
|
+
const shouldCommitToPod = input.commit && !context.pendingOnly;
|
|
741
935
|
const item = row.schema
|
|
742
|
-
? await executeDescriptorRow(context, row, index,
|
|
743
|
-
: await executeRawRow(context, row, index,
|
|
744
|
-
|
|
936
|
+
? await executeDescriptorRow(context, row, index, shouldCommitToPod)
|
|
937
|
+
: await executeRawRow(context, row, index, shouldCommitToPod);
|
|
938
|
+
if (context.pendingOnly && input.commit) {
|
|
939
|
+
const outboxPath = context.outboxPath ?? getObjLocalOutboxPath();
|
|
940
|
+
appendObjLocalOutbox({
|
|
941
|
+
kind: 'xpod.obj.mutation',
|
|
942
|
+
version: 1,
|
|
943
|
+
status: 'pending',
|
|
944
|
+
createdAt: new Date().toISOString(),
|
|
945
|
+
webId: context.webId,
|
|
946
|
+
podRoot: context.podRoot,
|
|
947
|
+
row,
|
|
948
|
+
item,
|
|
949
|
+
}, outboxPath);
|
|
950
|
+
items.push({
|
|
951
|
+
...item,
|
|
952
|
+
code: 'pending_local',
|
|
953
|
+
pendingLocal: true,
|
|
954
|
+
outboxPath,
|
|
955
|
+
warnings: [
|
|
956
|
+
...(Array.isArray(item.warnings) ? item.warnings : []),
|
|
957
|
+
context.pendingWarning,
|
|
958
|
+
],
|
|
959
|
+
});
|
|
960
|
+
continue;
|
|
961
|
+
}
|
|
962
|
+
items.push(context.planningOnly
|
|
963
|
+
? {
|
|
964
|
+
...item,
|
|
965
|
+
planningOnly: true,
|
|
966
|
+
warnings: [
|
|
967
|
+
...(Array.isArray(item.warnings) ? item.warnings : []),
|
|
968
|
+
context.planningWarning,
|
|
969
|
+
],
|
|
970
|
+
}
|
|
971
|
+
: item);
|
|
745
972
|
}
|
|
746
973
|
catch (error) {
|
|
747
974
|
const err = error instanceof output_1.CliCommandError
|
|
@@ -752,11 +979,61 @@ async function executeRows(input) {
|
|
|
752
979
|
}
|
|
753
980
|
return items;
|
|
754
981
|
}
|
|
982
|
+
function mutationItemsResultCode(items, commit) {
|
|
983
|
+
if (!items.every((item) => item.ok))
|
|
984
|
+
return 'partial_failure';
|
|
985
|
+
if (items.some((item) => item.code === 'pending_local'))
|
|
986
|
+
return 'pending_local';
|
|
987
|
+
return commit ? 'committed' : 'plan_ready';
|
|
988
|
+
}
|
|
755
989
|
function printItems(items) {
|
|
756
990
|
for (const item of items) {
|
|
757
991
|
console.log(`${item.index}\t${item.ok ? item.code : `ERROR ${item.code}`}\t${String(item.subject ?? item.resourceUrl ?? item.message ?? '')}`);
|
|
758
992
|
}
|
|
759
993
|
}
|
|
994
|
+
const schemasCommand = {
|
|
995
|
+
command: 'schemas',
|
|
996
|
+
describe: 'List model-backed object schemas available to AI tools',
|
|
997
|
+
builder: (yargs) => objOptions(yargs)
|
|
998
|
+
.option('domain', { type: 'string', description: 'Filter schemas by domain such as capture or symphony' }),
|
|
999
|
+
handler: async (argv) => {
|
|
1000
|
+
try {
|
|
1001
|
+
const schemas = listSchemaDescriptors({ domain: argv.domain });
|
|
1002
|
+
if (argv.json) {
|
|
1003
|
+
(0, output_1.writeJsonResult)({ schemas }, 'schemas');
|
|
1004
|
+
return;
|
|
1005
|
+
}
|
|
1006
|
+
for (const descriptor of schemas) {
|
|
1007
|
+
console.log(`${String(descriptor.alias)}\t${String(descriptor.schema)}\t${String(descriptor.resourceKind)}`);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
catch (error) {
|
|
1011
|
+
(0, output_1.handleCliError)(error, argv.json);
|
|
1012
|
+
}
|
|
1013
|
+
},
|
|
1014
|
+
};
|
|
1015
|
+
const describeCommand = {
|
|
1016
|
+
command: 'describe <schema>',
|
|
1017
|
+
describe: 'Describe one model-backed object schema by URI or alias',
|
|
1018
|
+
builder: (yargs) => objOptions(yargs)
|
|
1019
|
+
.positional('schema', { type: 'string', demandOption: true, description: 'Schema URI or descriptor alias' }),
|
|
1020
|
+
handler: async (argv) => {
|
|
1021
|
+
try {
|
|
1022
|
+
const descriptor = describeSchemaDescriptor(argv.schema);
|
|
1023
|
+
if (!descriptor) {
|
|
1024
|
+
throw new output_1.CliCommandError('schema_unknown', `Schema is not known by @undefineds.co/models: ${argv.schema}`, 2);
|
|
1025
|
+
}
|
|
1026
|
+
if (argv.json) {
|
|
1027
|
+
(0, output_1.writeJsonResult)({ descriptor }, 'schema');
|
|
1028
|
+
return;
|
|
1029
|
+
}
|
|
1030
|
+
console.log(JSON.stringify(descriptor, null, 2));
|
|
1031
|
+
}
|
|
1032
|
+
catch (error) {
|
|
1033
|
+
(0, output_1.handleCliError)(error, argv.json);
|
|
1034
|
+
}
|
|
1035
|
+
},
|
|
1036
|
+
};
|
|
760
1037
|
const importCommand = {
|
|
761
1038
|
command: 'import <file>',
|
|
762
1039
|
describe: 'Import descriptor-backed or explicit raw JSONL rows',
|
|
@@ -772,9 +1049,7 @@ const importCommand = {
|
|
|
772
1049
|
rows: await readJsonl(argv.file),
|
|
773
1050
|
commit: argv.commit === true,
|
|
774
1051
|
});
|
|
775
|
-
const code = items.
|
|
776
|
-
? (argv.commit ? 'committed' : 'plan_ready')
|
|
777
|
-
: 'partial_failure';
|
|
1052
|
+
const code = mutationItemsResultCode(items, argv.commit === true);
|
|
778
1053
|
if (argv.json) {
|
|
779
1054
|
(0, output_1.writeJsonItems)(items, code);
|
|
780
1055
|
return;
|
|
@@ -794,6 +1069,7 @@ const upsertCommand = {
|
|
|
794
1069
|
builder: (yargs) => objOptions(yargs)
|
|
795
1070
|
.option('schema', { type: 'string', demandOption: true, description: 'Schema URI or descriptor alias' })
|
|
796
1071
|
.option('from', { type: 'string', demandOption: true, description: 'JSONL file to read, or - for stdin' })
|
|
1072
|
+
.nargs('from', 1)
|
|
797
1073
|
.option('dry-run', { type: 'boolean', description: 'Validate and print a plan without writing' })
|
|
798
1074
|
.option('commit', { type: 'boolean', description: 'Commit the validated mutations' })
|
|
799
1075
|
.check(mutationModeCheck),
|
|
@@ -805,9 +1081,7 @@ const upsertCommand = {
|
|
|
805
1081
|
defaultSchema: resolveDescriptor(argv.schema).uri,
|
|
806
1082
|
commit: argv.commit === true,
|
|
807
1083
|
});
|
|
808
|
-
const code = items.
|
|
809
|
-
? (argv.commit ? 'committed' : 'plan_ready')
|
|
810
|
-
: 'partial_failure';
|
|
1084
|
+
const code = mutationItemsResultCode(items, argv.commit === true);
|
|
811
1085
|
if (argv.json) {
|
|
812
1086
|
(0, output_1.writeJsonItems)(items, code);
|
|
813
1087
|
return;
|
|
@@ -1044,6 +1318,8 @@ exports.objCommand = {
|
|
|
1044
1318
|
command: 'obj',
|
|
1045
1319
|
describe: 'Descriptor-backed object transport',
|
|
1046
1320
|
builder: (yargs) => yargs
|
|
1321
|
+
.command(schemasCommand)
|
|
1322
|
+
.command(describeCommand)
|
|
1047
1323
|
.command(exportCommand)
|
|
1048
1324
|
.command(importCommand)
|
|
1049
1325
|
.command(getCommand)
|