@seed-hypermedia/cli 0.0.8 → 0.0.10
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.js +164 -121
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6032,6 +6032,87 @@ function isSurrogate(s, i) {
|
|
|
6032
6032
|
const code = s.charCodeAt(i);
|
|
6033
6033
|
return 55296 <= code && code <= 56319;
|
|
6034
6034
|
}
|
|
6035
|
+
async function resolveHypermediaUrl(url) {
|
|
6036
|
+
let latest = false;
|
|
6037
|
+
let blockRef = null;
|
|
6038
|
+
let blockRange = null;
|
|
6039
|
+
let panel = null;
|
|
6040
|
+
try {
|
|
6041
|
+
const parsedUrl = new URL(url);
|
|
6042
|
+
const hasVersion = parsedUrl.searchParams.has("v");
|
|
6043
|
+
const hasLatest = parsedUrl.searchParams.has("l");
|
|
6044
|
+
panel = parsedUrl.searchParams.get("panel");
|
|
6045
|
+
if (parsedUrl.hash) {
|
|
6046
|
+
const fragment = parseFragment(parsedUrl.hash.slice(1));
|
|
6047
|
+
if (fragment) {
|
|
6048
|
+
blockRef = fragment.blockId;
|
|
6049
|
+
if ("start" in fragment && fragment.start !== undefined) {
|
|
6050
|
+
blockRange = { start: fragment.start, end: fragment.end };
|
|
6051
|
+
} else if ("expanded" in fragment && fragment.expanded) {
|
|
6052
|
+
blockRange = { expanded: fragment.expanded };
|
|
6053
|
+
}
|
|
6054
|
+
}
|
|
6055
|
+
}
|
|
6056
|
+
latest = blockRef ? false : hasLatest || !hasVersion;
|
|
6057
|
+
} catch {}
|
|
6058
|
+
const response = await fetch(url, {
|
|
6059
|
+
method: "OPTIONS"
|
|
6060
|
+
});
|
|
6061
|
+
if (response.status === 200) {
|
|
6062
|
+
const rawId = response.headers.get("x-hypermedia-id");
|
|
6063
|
+
const id = rawId ? decodeURIComponent(rawId) : null;
|
|
6064
|
+
const version = response.headers.get("x-hypermedia-version");
|
|
6065
|
+
const encodedTitle = response.headers.get("x-hypermedia-title");
|
|
6066
|
+
const title = encodedTitle ? decodeURIComponent(encodedTitle) : null;
|
|
6067
|
+
const rawTarget = response.headers.get("x-hypermedia-target");
|
|
6068
|
+
const target = rawTarget ? unpackHmId(decodeURIComponent(rawTarget)) : null;
|
|
6069
|
+
const rawAuthors = response.headers.get("x-hypermedia-authors");
|
|
6070
|
+
const authors = rawAuthors ? decodeURIComponent(rawAuthors).split(",").map((author) => unpackHmId(author)) : null;
|
|
6071
|
+
const type = response.headers.get("x-hypermedia-type");
|
|
6072
|
+
if (id) {
|
|
6073
|
+
const hmId = unpackHmId(id);
|
|
6074
|
+
const resolvedVersion = version ?? hmId?.version ?? null;
|
|
6075
|
+
let siteHostname = null;
|
|
6076
|
+
try {
|
|
6077
|
+
const inputUrl = new URL(url);
|
|
6078
|
+
if (!inputUrl.pathname.startsWith("/hm/")) {
|
|
6079
|
+
siteHostname = inputUrl.origin;
|
|
6080
|
+
}
|
|
6081
|
+
} catch {}
|
|
6082
|
+
return {
|
|
6083
|
+
id,
|
|
6084
|
+
hmId: hmId ? {
|
|
6085
|
+
...hmId,
|
|
6086
|
+
version: resolvedVersion,
|
|
6087
|
+
latest,
|
|
6088
|
+
blockRef,
|
|
6089
|
+
blockRange,
|
|
6090
|
+
hostname: siteHostname || hmId.hostname
|
|
6091
|
+
} : null,
|
|
6092
|
+
version,
|
|
6093
|
+
title,
|
|
6094
|
+
target,
|
|
6095
|
+
authors,
|
|
6096
|
+
type,
|
|
6097
|
+
panel
|
|
6098
|
+
};
|
|
6099
|
+
}
|
|
6100
|
+
return null;
|
|
6101
|
+
}
|
|
6102
|
+
return null;
|
|
6103
|
+
}
|
|
6104
|
+
async function resolveId(input) {
|
|
6105
|
+
const parsed = unpackHmId(input);
|
|
6106
|
+
if (parsed)
|
|
6107
|
+
return parsed;
|
|
6108
|
+
if (input.startsWith("http://") || input.startsWith("https://")) {
|
|
6109
|
+
const resolved = await resolveHypermediaUrl(input);
|
|
6110
|
+
if (resolved?.hmId)
|
|
6111
|
+
return resolved.hmId;
|
|
6112
|
+
throw new Error(`URL does not appear to be a Seed Hypermedia resource: ${input}`);
|
|
6113
|
+
}
|
|
6114
|
+
throw new Error(`Invalid Hypermedia ID: ${input}`);
|
|
6115
|
+
}
|
|
6035
6116
|
var BlockRangeSchema, unpackedHmIdSchema, HMBlockChildrenTypeSchema, HMEmbedViewSchema, HMQueryStyleSchema, baseAnnotationProperties, BoldAnnotationSchema, ItalicAnnotationSchema, UnderlineAnnotationSchema, StrikeAnnotationSchema, CodeAnnotationSchema, LinkAnnotationSchema, InlineEmbedAnnotationSchema, HighlightAnnotationSchema, HMAnnotationSchema, HMAnnotationsSchema, blockBaseProperties, textBlockProperties, parentBlockAttributes, HMBlockParagraphSchema, HMBlockHeadingSchema, HMBlockCodeSchema, HMBlockMathSchema, HMBlockImageSchema, HMBlockVideoSchema, HMBlockFileSchema, HMBlockButtonAlignmentSchema, HMBlockButtonSchema, HMBlockEmbedSchema, HMBlockWebEmbedSchema, HMBlockNostrSchema, HMTimestampSchema, HMBlockNodeSchema, HMDocumentMetadataSchema, visibilityMap, HMResourceVisibilitySchema, HMCommentSchema, HMBreadcrumbSchema, HMCommentGroupSchema, HMExternalCommentGroupSchema, HMActivitySummarySchema, HMGenerationInfoSchema, HMRedirectInfoSchema, HMDocumentInfoSchema, HMQueryResultSchema, HMRoleSchema, HMMetadataPayloadSchema, HMAccountPayloadSchema, HMAccountNotFoundSchema, HMAccountResultSchema, HMSiteMemberSchema, HMAccountsMetadataSchema, HMQueryInclusionSchema, HMQuerySortSchema, HMQuerySchema, HMBlockQuerySchema, HMBlockGroupSchema, HMBlockLinkSchema, HMBlockKnownSchema, HMBlockUnknownSchema, HMBlockSchema, knownBlockTypes, HMDocumentSchema, HMResourceDocumentSchema, HMResourceCommentSchema, HMResourceRedirectSchema, HMResourceNotFoundSchema, HMResourceTombstoneSchema, HMResourceErrorSchema, HMResourceSchema, HMResolvedResourceSchema, HMContactSubscribeSchema, HMContactRecordSchema, HMAccountContactsRequestSchema, HMCommentDraftSchema, HMListedCommentDraftSchema, HMHostConfigSchema, HMContactSchema, HMContactItemSchema, HMCapabilitySchema, siteDiscoverRequestSchema, HMPeerConnectionRequestSchema, ParsedFragmentSchema, HMCitationCommentSourceSchema, HMCitationDocumentSourceSchema, HMCitationSchema, DeviceLinkSessionSchema, HMNavigationItemSchema, HMDraftContentSchema, HMDraftMetaBaseSchema, draftLocationRefinement = (data) => data.editUid || data.locationUid, HMDraftMetaSchema, HMListedDraftSchema, HMListedDraftReadSchema, HMSubjectContactsRequestSchema, HMResourceRequestSchema, HMResourceMetadataRequestSchema, HMAccountRequestSchema, HMCommentRequestSchema, HMSearchInputSchema, HMSearchResultItemSchema, HMSearchPayloadSchema, HMSearchRequestSchema, HMQueryRequestSchema, HMListCommentsInputSchema, HMListCommentsOutputSchema, HMListCommentsRequestSchema, HMListDiscussionsInputSchema, HMListDiscussionsOutputSchema, HMListDiscussionsRequestSchema, HMListCommentsByReferenceInputSchema, HMListCommentsByReferenceRequestSchema, HMGetCommentReplyCountInputSchema, HMGetCommentReplyCountRequestSchema, HMListEventsInputSchema, HMLoadedEventSchema, HMListEventsOutputSchema, HMListEventsRequestSchema, HMListAccountsOutputSchema, HMListAccountsInputSchema, HMListAccountsRequestSchema, HMGetCIDOutputSchema, HMGetCIDInputSchema, HMGetCIDRequestSchema, HMListCommentsByAuthorOutputSchema, HMListCommentsByAuthorInputSchema, HMListCommentsByAuthorRequestSchema, HMRawMentionSchema, HMListCitationsOutputSchema, HMListCitationsInputSchema, HMListCitationsRequestSchema, HMRawDocumentChangeSchema, HMListChangesOutputSchema, HMListChangesInputSchema, HMListChangesRequestSchema, HMRawCapabilitySchema, HMListCapabilitiesOutputSchema, HMListCapabilitiesInputSchema, HMListCapabilitiesRequestSchema, HMInteractionSummaryInputSchema, HMInteractionSummaryOutputSchema, HMInteractionSummaryRequestSchema, HMPublishBlobsOutputSchema, HMPublishBlobsInputSchema, HMPublishBlobsRequestSchema, ProtoAnnotationSchema, ProtoBlockSchema, ProtoSetAttributeValueSchema, ProtoDocumentChangeSchema, HMPrepareDocumentChangeInputSchema, HMPrepareDocumentChangeOutputSchema, HMPrepareDocumentChangeRequestSchema, HMListCommentVersionsInputSchema, HMListCommentVersionsOutputSchema, HMListCommentVersionsRequestSchema, HMGetRequestSchema, HMActionSchema, HMRequestSchema, HYPERMEDIA_SCHEME = "hm", STATIC_HM_PATHS;
|
|
6036
6117
|
var init_hm_types = __esm(() => {
|
|
6037
6118
|
init_zod();
|
|
@@ -138238,6 +138319,8 @@ __export(exports_src2, {
|
|
|
138238
138319
|
signDocumentChange: () => signDocumentChange,
|
|
138239
138320
|
shouldAutoLinkParent: () => shouldAutoLinkParent2,
|
|
138240
138321
|
serializeBlockRange: () => serializeBlockRange,
|
|
138322
|
+
resolveId: () => resolveId,
|
|
138323
|
+
resolveHypermediaUrl: () => resolveHypermediaUrl,
|
|
138241
138324
|
resolveFileLinksInBlocks: () => resolveFileLinksInBlocks2,
|
|
138242
138325
|
resolveDocumentState: () => resolveDocumentState2,
|
|
138243
138326
|
pushSpanToAnnotation: () => pushSpanToAnnotation2,
|
|
@@ -161018,43 +161101,52 @@ __export(exports_nanoid, {
|
|
|
161018
161101
|
customRandom: () => customRandom,
|
|
161019
161102
|
customAlphabet: () => customAlphabet
|
|
161020
161103
|
});
|
|
161021
|
-
import {
|
|
161022
|
-
|
|
161104
|
+
import { webcrypto as crypto4 } from "node:crypto";
|
|
161105
|
+
function fillPool(bytes) {
|
|
161023
161106
|
if (!pool2 || pool2.length < bytes) {
|
|
161024
161107
|
pool2 = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
|
|
161025
|
-
|
|
161108
|
+
crypto4.getRandomValues(pool2);
|
|
161026
161109
|
poolOffset = 0;
|
|
161027
161110
|
} else if (poolOffset + bytes > pool2.length) {
|
|
161028
|
-
|
|
161111
|
+
crypto4.getRandomValues(pool2);
|
|
161029
161112
|
poolOffset = 0;
|
|
161030
161113
|
}
|
|
161031
161114
|
poolOffset += bytes;
|
|
161032
|
-
}
|
|
161033
|
-
|
|
161115
|
+
}
|
|
161116
|
+
function random(bytes) {
|
|
161117
|
+
fillPool(bytes |= 0);
|
|
161034
161118
|
return pool2.subarray(poolOffset - bytes, poolOffset);
|
|
161035
|
-
}
|
|
161119
|
+
}
|
|
161120
|
+
function customRandom(alphabet2, defaultSize, getRandom) {
|
|
161036
161121
|
let mask = (2 << 31 - Math.clz32(alphabet2.length - 1 | 1)) - 1;
|
|
161037
161122
|
let step = Math.ceil(1.6 * mask * defaultSize / alphabet2.length);
|
|
161038
161123
|
return (size = defaultSize) => {
|
|
161124
|
+
if (!size)
|
|
161125
|
+
return "";
|
|
161039
161126
|
let id = "";
|
|
161040
161127
|
while (true) {
|
|
161041
161128
|
let bytes = getRandom(step);
|
|
161042
161129
|
let i = step;
|
|
161043
161130
|
while (i--) {
|
|
161044
161131
|
id += alphabet2[bytes[i] & mask] || "";
|
|
161045
|
-
if (id.length
|
|
161132
|
+
if (id.length >= size)
|
|
161046
161133
|
return id;
|
|
161047
161134
|
}
|
|
161048
161135
|
}
|
|
161049
161136
|
};
|
|
161050
|
-
}
|
|
161051
|
-
|
|
161137
|
+
}
|
|
161138
|
+
function customAlphabet(alphabet2, size = 21) {
|
|
161139
|
+
return customRandom(alphabet2, size, random);
|
|
161140
|
+
}
|
|
161141
|
+
function nanoid(size = 21) {
|
|
161142
|
+
fillPool(size |= 0);
|
|
161052
161143
|
let id = "";
|
|
161053
161144
|
for (let i = poolOffset - size;i < poolOffset; i++) {
|
|
161054
161145
|
id += urlAlphabet[pool2[i] & 63];
|
|
161055
161146
|
}
|
|
161056
161147
|
return id;
|
|
161057
|
-
}
|
|
161148
|
+
}
|
|
161149
|
+
var POOL_SIZE_MULTIPLIER = 128, pool2, poolOffset;
|
|
161058
161150
|
var init_nanoid = () => {};
|
|
161059
161151
|
|
|
161060
161152
|
// node_modules/commander/esm.mjs
|
|
@@ -165376,6 +165468,18 @@ function esc(s) {
|
|
|
165376
165468
|
return `'${s.replace(/'/g, "'\\''")}'`;
|
|
165377
165469
|
}
|
|
165378
165470
|
|
|
165471
|
+
// src/utils/resolve-id.ts
|
|
165472
|
+
init_src16();
|
|
165473
|
+
async function resolveIdWithClient(rawId, globalOpts) {
|
|
165474
|
+
const parsed = unpackHmId(rawId);
|
|
165475
|
+
if (parsed) {
|
|
165476
|
+
return { id: parsed, client: getClient(globalOpts) };
|
|
165477
|
+
}
|
|
165478
|
+
const id = await resolveId(rawId);
|
|
165479
|
+
const origin = new URL(rawId).origin;
|
|
165480
|
+
return { id, client: createSeedClient(origin) };
|
|
165481
|
+
}
|
|
165482
|
+
|
|
165379
165483
|
// src/utils/signer.ts
|
|
165380
165484
|
function createSignerFromKey(key) {
|
|
165381
165485
|
return {
|
|
@@ -165420,6 +165524,16 @@ async function resolveFileLinks(nodes) {
|
|
|
165420
165524
|
}
|
|
165421
165525
|
|
|
165422
165526
|
// src/commands/document.ts
|
|
165527
|
+
async function resolveCapability(client, targetAccount, signerAccount) {
|
|
165528
|
+
if (targetAccount === signerAccount)
|
|
165529
|
+
return;
|
|
165530
|
+
const targetId = unpackHmId3(`hm://${targetAccount}`);
|
|
165531
|
+
if (!targetId)
|
|
165532
|
+
return;
|
|
165533
|
+
const caps = await client.request("ListCapabilities", { targetId });
|
|
165534
|
+
const match = caps.capabilities.find((c) => c.delegate === signerAccount && (c.role === "WRITER" || c.role === "AGENT"));
|
|
165535
|
+
return match?.id;
|
|
165536
|
+
}
|
|
165423
165537
|
async function readStdinBinary() {
|
|
165424
165538
|
const chunks = [];
|
|
165425
165539
|
for await (const chunk of process.stdin) {
|
|
@@ -165524,9 +165638,8 @@ async function readInput(options2) {
|
|
|
165524
165638
|
}
|
|
165525
165639
|
function registerDocumentCommands(program2) {
|
|
165526
165640
|
const doc = program2.command("document").description("Manage documents (get, create, update, delete, fork, move, redirect, changes, stats, cid)");
|
|
165527
|
-
doc.command("get <id>").description("Fetch a document, comment, or entity by Hypermedia ID").option("-m, --metadata", "Fetch metadata only").option("-r, --resolve", "Resolve embeds, mentions, and queries in markdown output").option("-o, --output <file>", "Write output to file instead of stdout").option("-q, --quiet", "Output minimal info").action(async (id, options2, cmd) => {
|
|
165641
|
+
doc.command("get <id>").description("Fetch a document, comment, or entity by Hypermedia ID or URL").option("-m, --metadata", "Fetch metadata only").option("-r, --resolve", "Resolve embeds, mentions, and queries in markdown output").option("-o, --output <file>", "Write output to file instead of stdout").option("-q, --quiet", "Output minimal info").action(async (id, options2, cmd) => {
|
|
165528
165642
|
const globalOpts = cmd.optsWithGlobals();
|
|
165529
|
-
const client = getClient(globalOpts);
|
|
165530
165643
|
const format2 = getOutputFormat(globalOpts);
|
|
165531
165644
|
const pretty = isPretty(globalOpts);
|
|
165532
165645
|
const useStructuredOutput = !!(globalOpts.json || globalOpts.yaml);
|
|
@@ -165541,13 +165654,9 @@ function registerDocumentCommands(program2) {
|
|
|
165541
165654
|
}
|
|
165542
165655
|
}
|
|
165543
165656
|
try {
|
|
165657
|
+
const { id: resolvedId, client } = await resolveIdWithClient(id, globalOpts);
|
|
165544
165658
|
if (options2.metadata) {
|
|
165545
|
-
const
|
|
165546
|
-
if (!unpacked) {
|
|
165547
|
-
printError2(`Invalid Hypermedia ID: ${id}`);
|
|
165548
|
-
process.exit(1);
|
|
165549
|
-
}
|
|
165550
|
-
const result2 = await client.request("ResourceMetadata", unpacked);
|
|
165659
|
+
const result2 = await client.request("ResourceMetadata", resolvedId);
|
|
165551
165660
|
if (globalOpts.quiet || options2.quiet) {
|
|
165552
165661
|
emit(result2.metadata?.name || result2.id.id);
|
|
165553
165662
|
} else {
|
|
@@ -165555,12 +165664,7 @@ function registerDocumentCommands(program2) {
|
|
|
165555
165664
|
}
|
|
165556
165665
|
return;
|
|
165557
165666
|
}
|
|
165558
|
-
const
|
|
165559
|
-
if (!resourceId) {
|
|
165560
|
-
printError2(`Invalid Hypermedia ID: ${id}`);
|
|
165561
|
-
process.exit(1);
|
|
165562
|
-
}
|
|
165563
|
-
const result = await client.request("Resource", resourceId);
|
|
165667
|
+
const result = await client.request("Resource", resolvedId);
|
|
165564
165668
|
if (globalOpts.quiet || options2.quiet) {
|
|
165565
165669
|
if (result.type === "document") {
|
|
165566
165670
|
emit(result.document.metadata?.name || result.id.id);
|
|
@@ -165604,7 +165708,7 @@ function registerDocumentCommands(program2) {
|
|
|
165604
165708
|
process.exit(1);
|
|
165605
165709
|
}
|
|
165606
165710
|
});
|
|
165607
|
-
doc.command("create").description("Create a new document from markdown, JSON blocks, or PDF").option("-f, --file <path>", "Input file (format detected by extension: .md, .json, .pdf)").option("-p, --path <path>", 'Document path (e.g. "my-document")').option("--name <value>", "Document title (overrides frontmatter)").option("--summary <value>", "Document summary").option("--display-author <value>", 'Display author name (e.g. "Jane Doe")').option("--display-publish-time <value>", "Display publish time (YYYY-MM-DD)").option("--icon <value>", "Document icon (ipfs:// or file:// URL)").option("--cover <value>", "Cover image (ipfs:// or file:// URL)").option("--site-url <value>", "Site URL").option("--layout <value>", 'Document layout (e.g. "Seed/Experimental/Newspaper")').option("--show-outline", "Show document outline").option("--no-show-outline", "Hide document outline").option("--show-activity", "Show document activity").option("--no-show-activity", "Hide document activity").option("--content-width <value>", "Content width (S, M, L)").option("--seed-experimental-logo <value>", "Experimental logo (ipfs:// or file:// URL)").option("--seed-experimental-home-order <value>", "Home ordering (UpdatedFirst, CreatedFirst)").option("--import-categories <value>", "Import categories (comma-separated)").option("--import-tags <value>", "Import tags (comma-separated)").option("--grobid-url <url>", "GROBID server URL for PDF extraction").option("--dry-run", "Preview extracted content without publishing").option("--force", "Overwrite existing document at the same path (creates new lineage)").option("-k, --key <name>", "Signing key name or account ID").action(async (options2, cmd) => {
|
|
165711
|
+
doc.command("create").description("Create a new document from markdown, JSON blocks, or PDF").option("-f, --file <path>", "Input file (format detected by extension: .md, .json, .pdf)").option("-p, --path <path>", 'Document path (e.g. "my-document")').option("--name <value>", "Document title (overrides frontmatter)").option("--summary <value>", "Document summary").option("--display-author <value>", 'Display author name (e.g. "Jane Doe")').option("--display-publish-time <value>", "Display publish time (YYYY-MM-DD)").option("--icon <value>", "Document icon (ipfs:// or file:// URL)").option("--cover <value>", "Cover image (ipfs:// or file:// URL)").option("--site-url <value>", "Site URL").option("--layout <value>", 'Document layout (e.g. "Seed/Experimental/Newspaper")').option("--show-outline", "Show document outline").option("--no-show-outline", "Hide document outline").option("--show-activity", "Show document activity").option("--no-show-activity", "Hide document activity").option("--content-width <value>", "Content width (S, M, L)").option("--seed-experimental-logo <value>", "Experimental logo (ipfs:// or file:// URL)").option("--seed-experimental-home-order <value>", "Home ordering (UpdatedFirst, CreatedFirst)").option("--import-categories <value>", "Import categories (comma-separated)").option("--import-tags <value>", "Import tags (comma-separated)").option("--grobid-url <url>", "GROBID server URL for PDF extraction").option("--dry-run", "Preview extracted content without publishing").option("--force", "Overwrite existing document at the same path (creates new lineage)").option("-k, --key <name>", "Signing key name or account ID").option("-a, --account <uid>", "Target space/account UID (publish under a different account using a capability)").action(async (options2, cmd) => {
|
|
165608
165712
|
const globalOpts = cmd.optsWithGlobals();
|
|
165609
165713
|
const dev = !!globalOpts.dev;
|
|
165610
165714
|
try {
|
|
@@ -165636,7 +165740,14 @@ function registerDocumentCommands(program2) {
|
|
|
165636
165740
|
}
|
|
165637
165741
|
const client = getClient(globalOpts);
|
|
165638
165742
|
const key = resolveKey(options2.key, dev);
|
|
165639
|
-
const account = key.accountId;
|
|
165743
|
+
const account = options2.account || key.accountId;
|
|
165744
|
+
let capability;
|
|
165745
|
+
if (options2.account && options2.account !== key.accountId) {
|
|
165746
|
+
capability = await resolveCapability(client, options2.account, key.accountId);
|
|
165747
|
+
if (!capability) {
|
|
165748
|
+
throw new Error(`No WRITER or AGENT capability found for key ${key.accountId} on account ${options2.account}. ` + `Use "account capabilities hm://${options2.account}" to check available capabilities.`);
|
|
165749
|
+
}
|
|
165750
|
+
}
|
|
165640
165751
|
const { metadata: resolvedMeta, blobs: metaBlobs } = await resolveMetadataFileLinks(metadata);
|
|
165641
165752
|
const rawPath = options2.path || slugify2(resolvedMeta.name || "Untitled");
|
|
165642
165753
|
const path = rawPath.startsWith("/") ? rawPath : `/${rawPath}`;
|
|
@@ -165674,7 +165785,8 @@ function registerDocumentCommands(program2) {
|
|
|
165674
165785
|
path,
|
|
165675
165786
|
genesis: genesisBlock.cid.toString(),
|
|
165676
165787
|
version: changeBlock.cid.toString(),
|
|
165677
|
-
generation
|
|
165788
|
+
generation,
|
|
165789
|
+
capability
|
|
165678
165790
|
}, signer);
|
|
165679
165791
|
await client.publish({
|
|
165680
165792
|
blobs: [
|
|
@@ -165707,18 +165819,13 @@ function registerDocumentCommands(program2) {
|
|
|
165707
165819
|
doc.command("update <id>").description("Update document content and metadata (smart diff — only changed blocks are submitted)").option("-f, --file <path>", "Input file (format detected by extension: .md, .json). Diffs against existing content.").option("--name <value>", "Set document title").option("--summary <value>", "Set document summary").option("--display-author <value>", "Display author name").option("--display-publish-time <value>", "Display publish time (YYYY-MM-DD)").option("--icon <value>", "Document icon (ipfs:// or file:// URL)").option("--cover <value>", "Cover image (ipfs:// or file:// URL)").option("--site-url <value>", "Site URL").option("--layout <value>", "Document layout").option("--show-outline", "Show document outline").option("--no-show-outline", "Hide document outline").option("--show-activity", "Show document activity").option("--no-show-activity", "Hide document activity").option("--content-width <value>", "Content width (S, M, L)").option("--seed-experimental-logo <value>", "Experimental logo (ipfs:// or file:// URL)").option("--seed-experimental-home-order <value>", "Home ordering (UpdatedFirst, CreatedFirst)").option("--import-categories <value>", "Import categories (comma-separated)").option("--import-tags <value>", "Import tags (comma-separated)").option("--parent <blockId>", "Parent block ID for new content (default: root)").option("--delete-blocks <ids>", "Comma-separated block IDs to delete").option("-k, --key <name>", "Signing key name or account ID").action(async (id, options2, cmd) => {
|
|
165708
165820
|
const globalOpts = cmd.optsWithGlobals();
|
|
165709
165821
|
const dev = !!globalOpts.dev;
|
|
165710
|
-
const client = getClient(globalOpts);
|
|
165711
165822
|
try {
|
|
165823
|
+
const { id: resourceId, client } = await resolveIdWithClient(id, globalOpts);
|
|
165712
165824
|
const key = resolveKey(options2.key, dev);
|
|
165713
165825
|
const hasFileInput = !!options2.file;
|
|
165714
165826
|
const ops = [];
|
|
165715
165827
|
let fileBlobs = [];
|
|
165716
165828
|
let metaBlobs = [];
|
|
165717
|
-
const resourceId = unpackHmId3(id);
|
|
165718
|
-
if (!resourceId) {
|
|
165719
|
-
printError2(`Invalid Hypermedia ID: ${id}`);
|
|
165720
|
-
process.exit(1);
|
|
165721
|
-
}
|
|
165722
165829
|
const resource = await client.request("Resource", resourceId);
|
|
165723
165830
|
if (resource.type !== "document") {
|
|
165724
165831
|
printError2(`Resource is ${resource.type}, not a document.`);
|
|
@@ -165767,6 +165874,7 @@ function registerDocumentCommands(program2) {
|
|
|
165767
165874
|
const depCids = state.heads.map((h2) => CID.parse(h2));
|
|
165768
165875
|
const newDepth = state.headDepth + 1;
|
|
165769
165876
|
const signer = createSignerFromKey(key);
|
|
165877
|
+
const capability = await resolveCapability(client, docAccount, key.accountId);
|
|
165770
165878
|
const { unsignedBytes, ts } = createChangeOps({ ops, genesisCid, deps: depCids, depth: newDepth });
|
|
165771
165879
|
const changeBlock = await createChange(unsignedBytes, signer);
|
|
165772
165880
|
const generation = Number(ts);
|
|
@@ -165775,7 +165883,8 @@ function registerDocumentCommands(program2) {
|
|
|
165775
165883
|
path: docPath,
|
|
165776
165884
|
genesis: state.genesis,
|
|
165777
165885
|
version: changeBlock.cid.toString(),
|
|
165778
|
-
generation
|
|
165886
|
+
generation,
|
|
165887
|
+
capability
|
|
165779
165888
|
}, signer);
|
|
165780
165889
|
await client.publish({
|
|
165781
165890
|
blobs: [
|
|
@@ -165798,15 +165907,10 @@ function registerDocumentCommands(program2) {
|
|
|
165798
165907
|
doc.command("delete <id>").description("Delete a document by publishing a tombstone ref").option("-k, --key <name>", "Signing key name or account ID").action(async (id, _options, cmd) => {
|
|
165799
165908
|
const globalOpts = cmd.optsWithGlobals();
|
|
165800
165909
|
const dev = !!globalOpts.dev;
|
|
165801
|
-
const client = getClient(globalOpts);
|
|
165802
165910
|
try {
|
|
165911
|
+
const { id: unpacked, client } = await resolveIdWithClient(id, globalOpts);
|
|
165803
165912
|
const key = resolveKey(_options.key, dev);
|
|
165804
165913
|
const signer = createSignerFromKey(key);
|
|
165805
|
-
const unpacked = unpackHmId3(id);
|
|
165806
|
-
if (!unpacked) {
|
|
165807
|
-
printError2(`Invalid Hypermedia ID: ${id}`);
|
|
165808
|
-
process.exit(1);
|
|
165809
|
-
}
|
|
165810
165914
|
const resource = await client.request("Resource", unpacked);
|
|
165811
165915
|
if (resource.type !== "document") {
|
|
165812
165916
|
printError2(`Cannot delete: resource is ${resource.type}, not a document.`);
|
|
@@ -165814,11 +165918,13 @@ function registerDocumentCommands(program2) {
|
|
|
165814
165918
|
}
|
|
165815
165919
|
const doc2 = resource.document;
|
|
165816
165920
|
const generation = doc2.generationInfo ? Number(doc2.generationInfo.generation) : 0;
|
|
165921
|
+
const capability = await resolveCapability(client, unpacked.uid, key.accountId);
|
|
165817
165922
|
const refInput = await createTombstoneRef({
|
|
165818
165923
|
space: unpacked.uid,
|
|
165819
165924
|
path: hmIdPathToEntityQueryPath3(unpacked.path),
|
|
165820
165925
|
genesis: doc2.genesis,
|
|
165821
|
-
generation
|
|
165926
|
+
generation,
|
|
165927
|
+
capability
|
|
165822
165928
|
}, signer);
|
|
165823
165929
|
await client.publish(refInput);
|
|
165824
165930
|
if (!globalOpts.quiet)
|
|
@@ -165831,15 +165937,11 @@ function registerDocumentCommands(program2) {
|
|
|
165831
165937
|
doc.command("fork <sourceId> <destinationId>").description("Fork a document to a new location (creates a copy)").option("-k, --key <name>", "Signing key name or account ID").action(async (sourceId, destinationId, _options, cmd) => {
|
|
165832
165938
|
const globalOpts = cmd.optsWithGlobals();
|
|
165833
165939
|
const dev = !!globalOpts.dev;
|
|
165834
|
-
const client = getClient(globalOpts);
|
|
165835
165940
|
try {
|
|
165941
|
+
const { id: sourceUnpacked, client } = await resolveIdWithClient(sourceId, globalOpts);
|
|
165942
|
+
const { id: dest } = await resolveIdWithClient(destinationId, globalOpts);
|
|
165836
165943
|
const key = resolveKey(_options.key, dev);
|
|
165837
165944
|
const signer = createSignerFromKey(key);
|
|
165838
|
-
const sourceUnpacked = unpackHmId3(sourceId);
|
|
165839
|
-
if (!sourceUnpacked) {
|
|
165840
|
-
printError2(`Invalid source Hypermedia ID: ${sourceId}`);
|
|
165841
|
-
process.exit(1);
|
|
165842
|
-
}
|
|
165843
165945
|
const resource = await client.request("Resource", sourceUnpacked);
|
|
165844
165946
|
if (resource.type !== "document") {
|
|
165845
165947
|
printError2(`Cannot fork: source is ${resource.type}, not a document.`);
|
|
@@ -165848,11 +165950,6 @@ function registerDocumentCommands(program2) {
|
|
|
165848
165950
|
const doc2 = resource.document;
|
|
165849
165951
|
if (!doc2.generationInfo)
|
|
165850
165952
|
throw new Error("No generation info for source document");
|
|
165851
|
-
const dest = unpackHmId3(destinationId);
|
|
165852
|
-
if (!dest) {
|
|
165853
|
-
printError2(`Invalid destination Hypermedia ID: ${destinationId}`);
|
|
165854
|
-
process.exit(1);
|
|
165855
|
-
}
|
|
165856
165953
|
const refInput = await createVersionRef({
|
|
165857
165954
|
space: dest.uid,
|
|
165858
165955
|
path: hmIdPathToEntityQueryPath3(dest.path),
|
|
@@ -165873,20 +165970,11 @@ function registerDocumentCommands(program2) {
|
|
|
165873
165970
|
doc.command("move <sourceId> <destinationId>").description("Move a document to a new location (creates redirect at source)").option("-k, --key <name>", "Signing key name or account ID").action(async (sourceId, destinationId, _options, cmd) => {
|
|
165874
165971
|
const globalOpts = cmd.optsWithGlobals();
|
|
165875
165972
|
const dev = !!globalOpts.dev;
|
|
165876
|
-
const client = getClient(globalOpts);
|
|
165877
165973
|
try {
|
|
165974
|
+
const { id: source, client } = await resolveIdWithClient(sourceId, globalOpts);
|
|
165975
|
+
const { id: dest } = await resolveIdWithClient(destinationId, globalOpts);
|
|
165878
165976
|
const key = resolveKey(_options.key, dev);
|
|
165879
165977
|
const signer = createSignerFromKey(key);
|
|
165880
|
-
const source = unpackHmId3(sourceId);
|
|
165881
|
-
const dest = unpackHmId3(destinationId);
|
|
165882
|
-
if (!source) {
|
|
165883
|
-
printError2(`Invalid source Hypermedia ID: ${sourceId}`);
|
|
165884
|
-
process.exit(1);
|
|
165885
|
-
}
|
|
165886
|
-
if (!dest) {
|
|
165887
|
-
printError2(`Invalid destination Hypermedia ID: ${destinationId}`);
|
|
165888
|
-
process.exit(1);
|
|
165889
|
-
}
|
|
165890
165978
|
const resource = await client.request("Resource", source);
|
|
165891
165979
|
if (resource.type !== "document") {
|
|
165892
165980
|
printError2(`Cannot move: source is ${resource.type}, not a document.`);
|
|
@@ -165924,20 +166012,11 @@ function registerDocumentCommands(program2) {
|
|
|
165924
166012
|
doc.command("redirect <id>").description("Create a redirect from one document to another").requiredOption("--to <targetId>", "Target Hypermedia ID to redirect to").option("--republish", "Republish target content at this location").option("-k, --key <name>", "Signing key name or account ID").action(async (id, _options, cmd) => {
|
|
165925
166013
|
const globalOpts = cmd.optsWithGlobals();
|
|
165926
166014
|
const dev = !!globalOpts.dev;
|
|
165927
|
-
const client = getClient(globalOpts);
|
|
165928
166015
|
try {
|
|
166016
|
+
const { id: source, client } = await resolveIdWithClient(id, globalOpts);
|
|
166017
|
+
const { id: target } = await resolveIdWithClient(_options.to, globalOpts);
|
|
165929
166018
|
const key = resolveKey(_options.key, dev);
|
|
165930
166019
|
const signer = createSignerFromKey(key);
|
|
165931
|
-
const source = unpackHmId3(id);
|
|
165932
|
-
const target = unpackHmId3(_options.to);
|
|
165933
|
-
if (!source) {
|
|
165934
|
-
printError2(`Invalid source Hypermedia ID: ${id}`);
|
|
165935
|
-
process.exit(1);
|
|
165936
|
-
}
|
|
165937
|
-
if (!target) {
|
|
165938
|
-
printError2(`Invalid target Hypermedia ID: ${_options.to}`);
|
|
165939
|
-
process.exit(1);
|
|
165940
|
-
}
|
|
165941
166020
|
const resource = await client.request("Resource", source);
|
|
165942
166021
|
if (resource.type !== "document") {
|
|
165943
166022
|
printError2(`Cannot redirect: resource is ${resource.type}, not a document.`);
|
|
@@ -165964,15 +166043,10 @@ function registerDocumentCommands(program2) {
|
|
|
165964
166043
|
});
|
|
165965
166044
|
doc.command("changes <targetId>").description("List document change history").option("-q, --quiet", "Output CIDs and authors only").action(async (targetId, _options, cmd) => {
|
|
165966
166045
|
const globalOpts = cmd.optsWithGlobals();
|
|
165967
|
-
const client = getClient(globalOpts);
|
|
165968
166046
|
const format2 = getOutputFormat(globalOpts);
|
|
165969
166047
|
const pretty = isPretty(globalOpts);
|
|
165970
166048
|
try {
|
|
165971
|
-
const unpacked =
|
|
165972
|
-
if (!unpacked) {
|
|
165973
|
-
printError2(`Invalid Hypermedia ID: ${targetId}`);
|
|
165974
|
-
process.exit(1);
|
|
165975
|
-
}
|
|
166049
|
+
const { id: unpacked, client } = await resolveIdWithClient(targetId, globalOpts);
|
|
165976
166050
|
const result = await client.request("ListChanges", { targetId: unpacked });
|
|
165977
166051
|
if (globalOpts.quiet) {
|
|
165978
166052
|
result.changes.forEach((c) => {
|
|
@@ -165991,15 +166065,10 @@ function registerDocumentCommands(program2) {
|
|
|
165991
166065
|
});
|
|
165992
166066
|
doc.command("stats <id>").description("Get interaction statistics for a document").action(async (id, _options, cmd) => {
|
|
165993
166067
|
const globalOpts = cmd.optsWithGlobals();
|
|
165994
|
-
const client = getClient(globalOpts);
|
|
165995
166068
|
const format2 = getOutputFormat(globalOpts);
|
|
165996
166069
|
const pretty = isPretty(globalOpts);
|
|
165997
166070
|
try {
|
|
165998
|
-
const unpacked =
|
|
165999
|
-
if (!unpacked) {
|
|
166000
|
-
printError2(`Invalid Hypermedia ID: ${id}`);
|
|
166001
|
-
process.exit(1);
|
|
166002
|
-
}
|
|
166071
|
+
const { id: unpacked, client } = await resolveIdWithClient(id, globalOpts);
|
|
166003
166072
|
const result = await client.request("InteractionSummary", { id: unpacked });
|
|
166004
166073
|
console.log(formatOutput2(result, format2, pretty));
|
|
166005
166074
|
} catch (error) {
|
|
@@ -166133,17 +166202,12 @@ function registerCommentCommands(program2) {
|
|
|
166133
166202
|
process.exit(1);
|
|
166134
166203
|
}
|
|
166135
166204
|
});
|
|
166136
|
-
comment.command("list <targetId>").description("List comments on a document").option("-q, --quiet", "Output IDs and authors only").action(async (targetId, _options, cmd) => {
|
|
166205
|
+
comment.command("list <targetId>").description("List comments on a document or URL").option("-q, --quiet", "Output IDs and authors only").action(async (targetId, _options, cmd) => {
|
|
166137
166206
|
const globalOpts = cmd.optsWithGlobals();
|
|
166138
|
-
const client = getClient(globalOpts);
|
|
166139
166207
|
const format2 = getOutputFormat(globalOpts);
|
|
166140
166208
|
const pretty = isPretty(globalOpts);
|
|
166141
166209
|
try {
|
|
166142
|
-
const unpacked =
|
|
166143
|
-
if (!unpacked) {
|
|
166144
|
-
printError2(`Invalid Hypermedia ID: ${targetId}`);
|
|
166145
|
-
process.exit(1);
|
|
166146
|
-
}
|
|
166210
|
+
const { id: unpacked, client } = await resolveIdWithClient(targetId, globalOpts);
|
|
166147
166211
|
const result = await client.request("ListComments", { targetId: unpacked });
|
|
166148
166212
|
if (globalOpts.quiet) {
|
|
166149
166213
|
result.comments.forEach((c) => {
|
|
@@ -166158,17 +166222,13 @@ function registerCommentCommands(program2) {
|
|
|
166158
166222
|
process.exit(1);
|
|
166159
166223
|
}
|
|
166160
166224
|
});
|
|
166161
|
-
comment.command("create <targetId>").description("Create a comment on a document").option("--body <text>", "Comment text").option("--file <path>", "Read comment text from file").option("--reply <commentId>", "Reply to an existing comment").option("-k, --key <name>", "Signing key name or account ID").action(async (targetId, options2, cmd) => {
|
|
166225
|
+
comment.command("create <targetId>").description("Create a comment on a document or URL").option("--body <text>", "Comment text").option("--file <path>", "Read comment text from file").option("--reply <commentId>", "Reply to an existing comment").option("-k, --key <name>", "Signing key name or account ID").action(async (targetId, options2, cmd) => {
|
|
166162
166226
|
const globalOpts = cmd.optsWithGlobals();
|
|
166163
166227
|
const dev = !!globalOpts.dev;
|
|
166164
|
-
const client = getClient(globalOpts);
|
|
166165
166228
|
try {
|
|
166229
|
+
const { id: unpacked, client } = await resolveIdWithClient(targetId, globalOpts);
|
|
166166
166230
|
const key = resolveKey(options2.key, dev);
|
|
166167
166231
|
const text3 = readCommentText(options2);
|
|
166168
|
-
const unpacked = unpackHmId3(targetId);
|
|
166169
|
-
if (!unpacked) {
|
|
166170
|
-
throw new Error(`Invalid Hypermedia ID: ${targetId}`);
|
|
166171
|
-
}
|
|
166172
166232
|
const blockRef = unpacked.blockRef;
|
|
166173
166233
|
const resourceId = { ...unpacked, blockRef: null };
|
|
166174
166234
|
const resource = await client.request("Resource", resourceId);
|
|
@@ -166290,17 +166350,12 @@ function registerCommentCommands(program2) {
|
|
|
166290
166350
|
process.exit(1);
|
|
166291
166351
|
}
|
|
166292
166352
|
});
|
|
166293
|
-
comment.command("discussions <targetId>").description("List threaded discussions on a document").option("-c, --comment <id>", "Filter to specific thread").action(async (targetId, options2, cmd) => {
|
|
166353
|
+
comment.command("discussions <targetId>").description("List threaded discussions on a document or URL").option("-c, --comment <id>", "Filter to specific thread").action(async (targetId, options2, cmd) => {
|
|
166294
166354
|
const globalOpts = cmd.optsWithGlobals();
|
|
166295
|
-
const client = getClient(globalOpts);
|
|
166296
166355
|
const format2 = getOutputFormat(globalOpts);
|
|
166297
166356
|
const pretty = isPretty(globalOpts);
|
|
166298
166357
|
try {
|
|
166299
|
-
const unpacked =
|
|
166300
|
-
if (!unpacked) {
|
|
166301
|
-
printError2(`Invalid Hypermedia ID: ${targetId}`);
|
|
166302
|
-
process.exit(1);
|
|
166303
|
-
}
|
|
166358
|
+
const { id: unpacked, client } = await resolveIdWithClient(targetId, globalOpts);
|
|
166304
166359
|
const result = await client.request("ListDiscussions", { targetId: unpacked, commentId: options2.comment });
|
|
166305
166360
|
console.log(formatOutput2(result, format2, pretty));
|
|
166306
166361
|
} catch (error) {
|
|
@@ -166532,7 +166587,6 @@ Examples:
|
|
|
166532
166587
|
}
|
|
166533
166588
|
|
|
166534
166589
|
// src/commands/account.ts
|
|
166535
|
-
init_entity_id_url();
|
|
166536
166590
|
function registerAccountCommands(program2) {
|
|
166537
166591
|
const account = program2.command("account").description("Manage accounts (get, list, contacts, capabilities)");
|
|
166538
166592
|
account.command("get <uid>").description("Get account information").option("-q, --quiet", "Output ID only").action(async (uid, _options, cmd) => {
|
|
@@ -166597,15 +166651,10 @@ function registerAccountCommands(program2) {
|
|
|
166597
166651
|
});
|
|
166598
166652
|
account.command("capabilities <id>").description("List access control capabilities").action(async (id, _options, cmd) => {
|
|
166599
166653
|
const globalOpts = cmd.optsWithGlobals();
|
|
166600
|
-
const client = getClient(globalOpts);
|
|
166601
166654
|
const format2 = getOutputFormat(globalOpts);
|
|
166602
166655
|
const pretty = isPretty(globalOpts);
|
|
166603
166656
|
try {
|
|
166604
|
-
const unpacked =
|
|
166605
|
-
if (!unpacked) {
|
|
166606
|
-
printError2(`Invalid Hypermedia ID: ${id}`);
|
|
166607
|
-
process.exit(1);
|
|
166608
|
-
}
|
|
166657
|
+
const { id: unpacked, client } = await resolveIdWithClient(id, globalOpts);
|
|
166609
166658
|
const result = await client.request("ListCapabilities", { targetId: unpacked });
|
|
166610
166659
|
console.log(formatOutput2(result, format2, pretty));
|
|
166611
166660
|
} catch (error) {
|
|
@@ -166658,7 +166707,6 @@ function registerSearchCommand(program2) {
|
|
|
166658
166707
|
}
|
|
166659
166708
|
|
|
166660
166709
|
// src/commands/query.ts
|
|
166661
|
-
init_entity_id_url();
|
|
166662
166710
|
function registerQueryCommands(program2) {
|
|
166663
166711
|
program2.command("query <space>").description("List documents in a space").option("-p, --path <path>", "Path prefix").option("-m, --mode <mode>", "Query mode: Children or AllDescendants", "Children").option("-l, --limit <n>", "Limit results", parseInt).option("--sort <term>", "Sort by: Path, Title, CreateTime, UpdateTime, DisplayTime").option("--reverse", "Reverse sort order").option("-q, --quiet", "Output IDs and names only").action(async (space, options2, cmd) => {
|
|
166664
166712
|
const globalOpts = cmd.optsWithGlobals();
|
|
@@ -166723,15 +166771,10 @@ function registerQueryCommands(program2) {
|
|
|
166723
166771
|
});
|
|
166724
166772
|
program2.command("citations <id>").description("List documents citing this resource").option("-q, --quiet", "Output source IDs only").action(async (id, _options, cmd) => {
|
|
166725
166773
|
const globalOpts = cmd.optsWithGlobals();
|
|
166726
|
-
const client = getClient(globalOpts);
|
|
166727
166774
|
const format2 = getOutputFormat(globalOpts);
|
|
166728
166775
|
const pretty = isPretty(globalOpts);
|
|
166729
166776
|
try {
|
|
166730
|
-
const unpacked =
|
|
166731
|
-
if (!unpacked) {
|
|
166732
|
-
printError2(`Invalid Hypermedia ID: ${id}`);
|
|
166733
|
-
process.exit(1);
|
|
166734
|
-
}
|
|
166777
|
+
const { id: unpacked, client } = await resolveIdWithClient(id, globalOpts);
|
|
166735
166778
|
const result = await client.request("ListCitations", { targetId: unpacked });
|
|
166736
166779
|
if (globalOpts.quiet) {
|
|
166737
166780
|
result.citations.forEach((c) => {
|