Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
var WikiDeleteSpace = common.Shortcut{ Service: "wiki", Command: "+delete-space", Description: "Delete a wiki space, polling the async delete task when needed", Risk: "high-risk-write", Scopes: []string{"wiki:space:write_only", "wiki:space:read"}, AuthTypes: []string{"user", "bot"}, Flags: []common.Flag{ {Name: "space-id", Desc: "wiki space ID to delete", Required: true}, }, Tips: []string{ "Deletion is irreversible; double-check --space-id before running.", "This is a high-risk-write command; pass --yes to confirm the deletion.", "If the API returns a long-running task, this command polls for a bounded window and then prints a follow-up drive +task_result command.", }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { return validateWikiDeleteSpaceSpec(readWikiDeleteSpaceSpec(runtime)) }, DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI { return buildWikiDeleteSpaceDryRun(readWikiDeleteSpaceSpec(runtime)) }, Execute: func(ctx context.Context, runtime *common.RuntimeContext) error { spec := readWikiDeleteSpaceSpec(runtime) fmt.Fprintf(runtime.IO().ErrOut, "Deleting wiki space %s...\n", spec.SpaceID) out, err := runWikiDeleteSpace(ctx, wikiDeleteSpaceAPI{runtime: runtime}, runtime, spec) if err != nil { return err } runtime.Out(out, nil) return nil }, }
WikiDeleteSpace deletes a wiki space. The DELETE endpoint may complete synchronously (empty task_id) or return a task_id that must be polled against /open-apis/wiki/v2/tasks/:task_id with task_type=delete_space.
var WikiMove = common.Shortcut{ Service: "wiki", Command: "+move", Description: "Move a wiki node, or move a Drive document into Wiki", Risk: "write", Scopes: []string{"wiki:node:move", "wiki:node:read", "wiki:space:read"}, AuthTypes: []string{"user", "bot"}, Flags: []common.Flag{ {Name: "node-token", Desc: "wiki node token to move inside Wiki"}, {Name: "source-space-id", Desc: "source wiki space ID for --node-token; if omitted, it is resolved from the node token"}, {Name: "target-space-id", Desc: "target wiki space ID; required for docs-to-wiki, optional for node move when --target-parent-token is set"}, {Name: "target-parent-token", Desc: "target parent wiki node token; if omitted for docs-to-wiki, the document is moved to the target space root"}, {Name: "obj-type", Desc: "Drive document type for docs-to-wiki mode", Enum: wikiMoveObjectTypes}, {Name: "obj-token", Desc: "Drive document token for docs-to-wiki mode"}, {Name: "apply", Type: "bool", Desc: "submit a move request when the caller lacks permission to move the document immediately"}, }, Tips: []string{ "Use --node-token to move an existing wiki node inside or across wiki spaces.", "Use --obj-type and --obj-token to move a Drive document into Wiki.", "If docs-to-wiki returns a long-running task, this command polls for a bounded window and then prints a follow-up drive +task_result command.", }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { spec := readWikiMoveSpec(runtime) if runtime.As().IsBot() && spec.TargetSpaceID == wikiMyLibrarySpaceID { return output.ErrValidation("--target-space-id my_library is a per-user personal library alias and cannot be used with --as bot; resolve it to a real space_id first via `lark-cli wiki spaces get --params '{\"space_id\":\"my_library\"}' --as user`") } return validateWikiMoveSpec(spec) }, DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI { return buildWikiMoveDryRun(readWikiMoveSpec(runtime)) }, Execute: func(ctx context.Context, runtime *common.RuntimeContext) error { spec := readWikiMoveSpec(runtime) fmt.Fprintf(runtime.IO().ErrOut, "Running wiki move (%s)...\n", spec.Mode()) out, err := runWikiMove(ctx, wikiMoveAPI{runtime: runtime}, runtime, spec) if err != nil { return err } runtime.Out(out, nil) return nil }, }
WikiMove moves an existing wiki node inside Wiki or migrates a Drive document into Wiki with bounded polling for async task completion.
var WikiNodeCopy = common.Shortcut{ Service: "wiki", Command: "+node-copy", Description: "Copy a wiki node to a target space or parent node", Risk: "high-risk-write", Scopes: []string{"wiki:node:copy"}, AuthTypes: []string{"user", "bot"}, HasFormat: true, Flags: []common.Flag{ {Name: "space-id", Desc: "source wiki space ID", Required: true}, {Name: "node-token", Desc: "source node token to copy", Required: true}, {Name: "target-space-id", Desc: "target wiki space ID; required if --target-parent-node-token is not set"}, {Name: "target-parent-node-token", Desc: "target parent node token; required if --target-space-id is not set"}, {Name: "title", Desc: "new title for the copied node; leave empty to keep the original title"}, }, Tips: []string{ "At least one of --target-space-id or --target-parent-node-token must be provided.", "Omit --title to keep the original node title in the copy.", }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { if err := validateOptionalResourceName(strings.TrimSpace(runtime.Str("space-id")), "--space-id"); err != nil { return err } if err := validateOptionalResourceName(strings.TrimSpace(runtime.Str("node-token")), "--node-token"); err != nil { return err } targetSpaceID := strings.TrimSpace(runtime.Str("target-space-id")) targetParent := strings.TrimSpace(runtime.Str("target-parent-node-token")) if targetSpaceID == "" && targetParent == "" { return output.ErrValidation("at least one of --target-space-id or --target-parent-node-token is required") } if targetSpaceID != "" && targetParent != "" { return output.ErrValidation("--target-space-id and --target-parent-node-token are mutually exclusive; provide only one") } if err := validateOptionalResourceName(targetSpaceID, "--target-space-id"); err != nil { return err } return validateOptionalResourceName(targetParent, "--target-parent-node-token") }, DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI { spaceID := strings.TrimSpace(runtime.Str("space-id")) nodeToken := strings.TrimSpace(runtime.Str("node-token")) return common.NewDryRunAPI(). POST(fmt.Sprintf("/open-apis/wiki/v2/spaces/%s/nodes/%s/copy", validate.EncodePathSegment(spaceID), validate.EncodePathSegment(nodeToken))). Body(buildNodeCopyBody(runtime)). Set("space_id", spaceID). Set("node_token", nodeToken) }, Execute: func(ctx context.Context, runtime *common.RuntimeContext) error { spaceID := strings.TrimSpace(runtime.Str("space-id")) nodeToken := strings.TrimSpace(runtime.Str("node-token")) fmt.Fprintf(runtime.IO().ErrOut, "Copying wiki node %s from space %s\n", common.MaskToken(nodeToken), common.MaskToken(spaceID)) data, err := runtime.CallAPI("POST", fmt.Sprintf("/open-apis/wiki/v2/spaces/%s/nodes/%s/copy", validate.EncodePathSegment(spaceID), validate.EncodePathSegment(nodeToken)), nil, buildNodeCopyBody(runtime)) if err != nil { return err } node, err := parseWikiNodeRecord(common.GetMap(data, "node")) if err != nil { return err } fmt.Fprintf(runtime.IO().ErrOut, "Copied to node %s in space %s\n", common.MaskToken(node.NodeToken), common.MaskToken(node.SpaceID)) out := wikiNodeCopyOutput(node) if u := wikiNodeURL(runtime.Config.Brand, node); u != "" { out["url"] = u } runtime.OutFormat(out, nil, func(w io.Writer) { renderWikiNodeCopyPretty(w, out) }) return nil }, }
WikiNodeCopy copies a wiki node into a target space or under a target parent node.
var WikiNodeCreate = common.Shortcut{ Service: "wiki", Command: "+node-create", Description: "Create a wiki node with automatic space resolution", Risk: "write", Scopes: []string{"wiki:node:create", "wiki:node:read", "wiki:space:read"}, AuthTypes: []string{"user", "bot"}, Flags: []common.Flag{ {Name: "space-id", Desc: "target wiki space ID; use my_library for the personal document library"}, {Name: "parent-node-token", Desc: "parent wiki node token; if set, the new node is created under that parent"}, {Name: "title", Desc: "node title"}, {Name: "node-type", Default: wikiNodeTypeOrigin, Desc: "node type", Enum: []string{wikiNodeTypeOrigin, wikiNodeTypeShortcut}}, {Name: "obj-type", Default: "docx", Desc: "target object type", Enum: wikiObjectTypes}, {Name: "origin-node-token", Desc: "source node token when --node-type=shortcut"}, }, Tips: []string{ "If --space-id and --parent-node-token are both omitted, user identity falls back to my_library.", "Use --node-type shortcut --origin-node-token <token> to create a shortcut node.", }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { return validateWikiNodeCreateSpec(readWikiNodeCreateSpec(runtime), runtime.As()) }, DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI { dry := buildWikiNodeCreateDryRun(readWikiNodeCreateSpec(runtime)) if runtime.IsBot() { dry.Desc("After wiki node creation succeeds in bot mode, the CLI will also try to grant the current CLI user full_access (可管理权限) on the new wiki node.") } return dry }, Execute: func(ctx context.Context, runtime *common.RuntimeContext) error { spec := readWikiNodeCreateSpec(runtime) fmt.Fprintf(runtime.IO().ErrOut, "Creating wiki node...\n") execution, err := runWikiNodeCreate(ctx, wikiNodeCreateAPI{runtime: runtime}, runtime.As(), spec) if err != nil { return err } fmt.Fprintf(runtime.IO().ErrOut, "Created wiki node in space %s via %s.\n", execution.ResolvedSpace.SpaceID, execution.ResolvedSpace.ResolvedBy) runtime.Out(augmentWikiNodeCreateOutput(runtime, execution), nil) return nil }, }
WikiNodeCreate wraps wiki node creation with shortcut-specific ergonomics: it can infer the target space from the parent node or the caller's personal document library instead of forcing users to pass a numeric space ID first.
var WikiNodeDelete = common.Shortcut{ Service: "wiki", Command: "+node-delete", Description: "Delete a wiki node, polling the async delete task when needed", Risk: "high-risk-write", Scopes: []string{"wiki:node:create"}, AuthTypes: []string{"user", "bot"}, Flags: []common.Flag{ {Name: "node-token", Desc: "wiki node_token, cloud-doc obj_token, or a Lark URL embedding one of them", Required: true}, {Name: "obj-type", Desc: "token kind; no default — pass explicitly when --node-token is a raw token (URL inputs auto-infer)", Enum: wikiNodeDeleteObjTypes}, {Name: "space-id", Desc: "wiki space ID; auto-resolved via get_node when omitted"}, {Name: "include-children", Type: "bool", Default: "true", Desc: "cascade delete the subtree (default); pass --include-children=false to lift direct children up to the parent"}, }, Tips: []string{ "Deletion is irreversible; double-check --node-token and --obj-type before running.", "This is a high-risk-write command; pass --yes to confirm the deletion.", "--node-token accepts a raw token (wikcnXXX, docxXXX, ...) or a Lark URL like https://feishu.cn/wiki/<token> or https://feishu.cn/docx/<token>; URL paths also imply --obj-type.", "Run +node-get first to confirm space_id / obj_type when in doubt.", "Auto-resolving space_id (when --space-id is omitted) also calls get_node, which needs the wiki:node:retrieve scope; pass --space-id to skip that lookup if your token only carries wiki:node:create.", "Async deletes return a task_id; this command polls for a bounded window and then prints a follow-up drive +task_result command.", }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { _, err := readWikiNodeDeleteSpec(runtime) return err }, DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI { spec, err := readWikiNodeDeleteSpec(runtime) if err != nil { return common.NewDryRunAPI().Set("error", err.Error()) } return buildWikiNodeDeleteDryRun(spec) }, Execute: func(ctx context.Context, runtime *common.RuntimeContext) error { spec, err := readWikiNodeDeleteSpec(runtime) if err != nil { return err } out, err := runWikiNodeDelete(ctx, wikiNodeDeleteAPI{runtime: runtime}, runtime, spec) if err != nil { return err } runtime.Out(out, nil) return nil }, }
WikiNodeDelete deletes a wiki node (or pulls a cloud doc out of Wiki). The API mirrors +delete-space — synchronous on small deletes, async with a task_id for cascade deletes — so this shortcut shares the async-polling helper. Space ID is optional: when omitted, +node-delete first looks up the node via get_node to resolve the space ID so callers do not have to chain commands.
var WikiNodeGet = common.Shortcut{ Service: "wiki", Command: "+node-get", Description: "Get wiki node details by node_token, obj_token, or Lark URL", Risk: "read", Scopes: []string{"wiki:node:retrieve"}, AuthTypes: []string{"user", "bot"}, HasFormat: true, Flags: []common.Flag{ {Name: "token", Desc: "wiki node_token, obj_token, or a Lark URL embedding one of them", Required: true}, {Name: "obj-type", Desc: "obj_type when --token is an obj_token; auto-inferred from URL path when omitted", Enum: wikiNodeGetObjTypeEnum}, {Name: "space-id", Desc: "optional: assert the resolved node lives in this space"}, }, Tips: []string{ "--token accepts a raw token (wikcnXXX, docxXXX, ...) or a Lark URL like https://feishu.cn/wiki/<token> or https://feishu.cn/docx/<token>.", "For raw obj_tokens (not starting with wik), pass --obj-type so the API knows how to resolve them; URL inputs infer it from the path.", "Pair with +move / +node-copy / +delete-space to confirm space_id, obj_type, and parent before mutating.", }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { _, err := readWikiNodeGetSpec(runtime) return err }, DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI { spec, err := readWikiNodeGetSpec(runtime) if err != nil { return common.NewDryRunAPI().Set("error", err.Error()) } return buildWikiNodeGetDryRun(spec) }, Execute: func(ctx context.Context, runtime *common.RuntimeContext) error { spec, err := readWikiNodeGetSpec(runtime) if err != nil { return err } fmt.Fprintf(runtime.IO().ErrOut, "Fetching wiki node %s...\n", common.MaskToken(spec.Token)) data, err := runtime.CallAPI("GET", "/open-apis/wiki/v2/spaces/get_node", spec.RequestParams(), nil) if err != nil { return err } raw := common.GetMap(data, "node") node, err := parseWikiNodeRecord(raw) if err != nil { return err } if spec.SpaceID != "" && node.SpaceID != "" && spec.SpaceID != node.SpaceID { return output.ErrValidation( "--space-id %q does not match the resolved node space %q (node_token=%s)", spec.SpaceID, node.SpaceID, node.NodeToken, ) } if spec.SpaceID != "" && node.SpaceID == "" { fmt.Fprintf(runtime.IO().ErrOut, "Warning: --space-id %q could not be verified; the resolved node carries no space_id.\n", spec.SpaceID) } out := wikiNodeGetOutput(node, raw) runtime.OutFormat(out, nil, func(w io.Writer) { renderWikiNodeGetPretty(w, out) }) return nil }, }
WikiNodeGet wraps wiki.spaces.get_node so callers can resolve a node by node_token, obj_token, or a Lark URL without hand-rolling a `wiki spaces get_node --params ...` invocation. The shortcut prints a formatted view of the node (title / obj_type / obj_token / parent / creator / updated_at) and is intended as the "what am I about to touch?" step before +move / +node-copy / +delete-space.
var WikiNodeList = common.Shortcut{ Service: "wiki", Command: "+node-list", Description: "List wiki nodes in a space or under a parent node", Risk: "read", Scopes: []string{"wiki:node:retrieve"}, AuthTypes: []string{"user", "bot"}, HasFormat: true, Flags: []common.Flag{ {Name: "space-id", Desc: "wiki space ID; use my_library for the personal document library, or +space-list to discover other space IDs", Required: true}, {Name: "parent-node-token", Desc: "parent node token; if omitted, lists the root-level nodes of the space"}, {Name: "page-size", Type: "int", Default: strconv.Itoa(wikiNodeListDefaultPageSize), Desc: fmt.Sprintf("page size, 1-%d", wikiNodeListMaxPageSize)}, {Name: "page-token", Desc: "page token; implies single-page fetch (no auto-pagination)"}, {Name: "page-all", Type: "bool", Desc: "automatically paginate through all pages (capped by --page-limit)"}, {Name: "page-limit", Type: "int", Default: "10", Desc: "max pages to fetch with --page-all (default 10, 0 = unlimited)"}, }, Tips: []string{ "Default fetches a single page; pass --page-all to walk every page (large knowledge bases can be huge — keep an eye on --page-limit).", "Use --parent-node-token to drill into a sub-directory.", "Run +space-list first to discover your space IDs, including the personal document library.", "--space-id my_library is a per-user alias and is only valid with --as user.", }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { spaceID := strings.TrimSpace(runtime.Str("space-id")) if runtime.As().IsBot() && spaceID == wikiMyLibrarySpaceID { return output.ErrValidation("bot identity does not support --space-id my_library; use an explicit --space-id") } if err := validateOptionalResourceName(spaceID, "--space-id"); err != nil { return err } if err := validateOptionalResourceName(strings.TrimSpace(runtime.Str("parent-node-token")), "--parent-node-token"); err != nil { return err } return validateWikiListPagination(runtime, wikiNodeListMaxPageSize) }, DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI { spaceID := strings.TrimSpace(runtime.Str("space-id")) params := map[string]interface{}{"page_size": runtime.Int("page-size")} if pt := strings.TrimSpace(runtime.Str("parent-node-token")); pt != "" { params["parent_node_token"] = pt } if pt := strings.TrimSpace(runtime.Str("page-token")); pt != "" { params["page_token"] = pt } d := common.NewDryRunAPI() if wikiListShouldAutoPaginate(runtime) { d.Desc("Auto-paginates through all pages (capped by --page-limit when > 0)") } if spaceID == wikiMyLibrarySpaceID { return d. Desc("2-step orchestration: resolve my_library -> list nodes"). GET("/open-apis/wiki/v2/spaces/my_library"). Desc("[1] Resolve my_library space ID"). GET(fmt.Sprintf("/open-apis/wiki/v2/spaces/%s/nodes", "<resolved_space_id>")). Desc("[2] List nodes"). Params(params). Set("space_id", "<resolved_space_id>") } return d. GET(fmt.Sprintf("/open-apis/wiki/v2/spaces/%s/nodes", validate.EncodePathSegment(spaceID))). Params(params). Set("space_id", spaceID) }, Execute: func(ctx context.Context, runtime *common.RuntimeContext) error { warnIfConflictingPagingFlags(runtime) spaceID := strings.TrimSpace(runtime.Str("space-id")) if spaceID == wikiMyLibrarySpaceID { resolved, err := resolveMyLibrarySpaceID(runtime) if err != nil { return err } fmt.Fprintf(runtime.IO().ErrOut, "Resolved my_library to space %s\n", common.MaskToken(resolved)) spaceID = resolved } nodes, hasMore, nextToken, err := fetchWikiNodes(runtime, spaceID) if err != nil { return err } fmt.Fprintf(runtime.IO().ErrOut, "Found %d node(s)\n", len(nodes)) outData := map[string]interface{}{ "nodes": nodes, "has_more": hasMore, "page_token": nextToken, } runtime.OutFormat(outData, &output.Meta{Count: len(nodes)}, func(w io.Writer) { renderWikiNodesPretty(w, nodes, hasMore, nextToken) }) return nil }, }
WikiNodeList lists child nodes in a wiki space or under a parent node.
var WikiSpaceCreate = common.Shortcut{ Service: "wiki", Command: "+space-create", Description: "Create a wiki space", Risk: "write", Scopes: []string{"wiki:space:write_only"}, AuthTypes: []string{"user"}, Flags: []common.Flag{ {Name: "name", Desc: "wiki space name", Required: true}, {Name: "description", Desc: "wiki space description"}, }, Tips: []string{ "Only --as user is supported; the create API does not accept a tenant/bot token.", "The underlying spaces.create API is flagged danger in the schema browser; a space is recoverable via `wiki +delete-space` if created by mistake.", "--name is required: an unnamed space is almost always an accident and is hard to find later.", }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { _, err := readWikiSpaceCreateSpec(runtime) return err }, DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI { spec, err := readWikiSpaceCreateSpec(runtime) if err != nil { return common.NewDryRunAPI().Set("error", err.Error()) } return common.NewDryRunAPI(). POST(wikiSpacesAPIPath). Body(spec.RequestBody()) }, Execute: func(ctx context.Context, runtime *common.RuntimeContext) error { spec, err := readWikiSpaceCreateSpec(runtime) if err != nil { return err } fmt.Fprintf(runtime.IO().ErrOut, "Creating wiki space %q...\n", spec.Name) data, err := runtime.CallAPI("POST", wikiSpacesAPIPath, nil, spec.RequestBody()) if err != nil { return err } raw := common.GetMap(data, "space") if raw == nil { return output.Errorf(output.ExitAPI, "api_error", "wiki space create returned no space") } out := wikiSpaceCreateOutput(raw) fmt.Fprintf(runtime.IO().ErrOut, "Created wiki space %s\n", common.MaskToken(common.GetString(out, "space_id"))) runtime.Out(out, nil) return nil }, }
WikiSpaceCreate wraps wiki.spaces.create. The raw API only takes two optional string fields, so the shortcut's value is flag ergonomics (no hand-written --params JSON), output flattening (data.space.* lifted to the top level), and a dry-run preview.
The API only accepts a user access token (no tenant/bot), so AuthTypes is user-only — the framework's CheckIdentity rejects --as bot for us.
var WikiSpaceList = common.Shortcut{ Service: "wiki", Command: "+space-list", Description: "List wiki spaces accessible to the caller", Risk: "read", Scopes: []string{"wiki:space:retrieve"}, AuthTypes: []string{"user", "bot"}, HasFormat: true, Flags: []common.Flag{ {Name: "page-size", Type: "int", Default: strconv.Itoa(wikiSpaceListDefaultPageSize), Desc: fmt.Sprintf("page size, 1-%d", wikiSpaceListMaxPageSize)}, {Name: "page-token", Desc: "page token; implies single-page fetch (no auto-pagination)"}, {Name: "page-all", Type: "bool", Desc: "automatically paginate through all pages (capped by --page-limit)"}, {Name: "page-limit", Type: "int", Default: "10", Desc: "max pages to fetch with --page-all (default 10, 0 = unlimited)"}, }, Tips: []string{ "Default fetches a single page (matches other list shortcuts in this CLI); pass --page-all to pull every page.", "The underlying API never returns the my_library personal library; resolve it via `wiki spaces get --params '{\"space_id\":\"my_library\"}'`.", }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { return validateWikiListPagination(runtime, wikiSpaceListMaxPageSize) }, DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI { params := map[string]interface{}{"page_size": runtime.Int("page-size")} if pt := strings.TrimSpace(runtime.Str("page-token")); pt != "" { params["page_token"] = pt } dry := common.NewDryRunAPI() if wikiListShouldAutoPaginate(runtime) { dry.Desc("Auto-paginates through all pages (capped by --page-limit when > 0)") } return dry.GET(wikiSpacesAPIPath).Params(params) }, Execute: func(ctx context.Context, runtime *common.RuntimeContext) error { warnIfConflictingPagingFlags(runtime) spaces, hasMore, nextToken, err := fetchWikiSpaces(runtime) if err != nil { return err } fmt.Fprintf(runtime.IO().ErrOut, "Found %d wiki space(s)\n", len(spaces)) outData := map[string]interface{}{ "spaces": spaces, "has_more": hasMore, "page_token": nextToken, } runtime.OutFormat(outData, &output.Meta{Count: len(spaces)}, func(w io.Writer) { renderWikiSpacesPretty(w, spaces, hasMore, nextToken) }) return nil }, }
WikiSpaceList lists all wiki spaces the caller has access to.
Functions ¶
Types ¶
This section is empty.