@maplab/hyperdoc 0.3.0 → 0.4.0

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 CHANGED
@@ -17793,6 +17793,28 @@ var import_open = __toESM(require("open"));
17793
17793
  var import_fs13 = __toESM(require("fs"));
17794
17794
  var import_path16 = __toESM(require("path"));
17795
17795
  var import_v4 = require("zod/v4");
17796
+ function readProjectsFile(filePath) {
17797
+ try {
17798
+ const raw = import_fs13.default.readFileSync(filePath, "utf-8");
17799
+ const parsed = JSON.parse(raw);
17800
+ if (Array.isArray(parsed)) return parsed;
17801
+ } catch {
17802
+ }
17803
+ return [];
17804
+ }
17805
+ function writeProjectsFile(filePath, contents) {
17806
+ const dir = import_path16.default.dirname(filePath);
17807
+ if (!import_fs13.default.existsSync(dir)) import_fs13.default.mkdirSync(dir, { recursive: true });
17808
+ import_fs13.default.writeFileSync(filePath, JSON.stringify(contents, null, 2) + "\n", "utf-8");
17809
+ }
17810
+ function requireProjectsFile(filePath) {
17811
+ if (!filePath)
17812
+ throw new TRPCError({
17813
+ code: "INTERNAL_SERVER_ERROR",
17814
+ message: "No projects file configured"
17815
+ });
17816
+ return filePath;
17817
+ }
17796
17818
  var listProjects = (t6) => t6.procedure.query(({ ctx }) => ctx.loadProjects());
17797
17819
  var createProject = (t6) => t6.procedure.input(
17798
17820
  import_v4.z.object({
@@ -17813,25 +17835,21 @@ var createProject = (t6) => t6.procedure.input(
17813
17835
  const resolvedRootDirs = (input.rootDirs ?? []).map(
17814
17836
  (d3) => import_path16.default.resolve(d3)
17815
17837
  );
17816
- for (const dir2 of resolvedDocsDirs) {
17817
- if (!import_fs13.default.existsSync(dir2))
17838
+ for (const dir of resolvedDocsDirs) {
17839
+ if (!import_fs13.default.existsSync(dir))
17818
17840
  throw new TRPCError({
17819
17841
  code: "BAD_REQUEST",
17820
- message: `Directory does not exist: ${dir2}`
17842
+ message: `Directory does not exist: ${dir}`
17821
17843
  });
17822
17844
  }
17823
- for (const dir2 of resolvedRootDirs) {
17824
- if (!import_fs13.default.existsSync(dir2))
17845
+ for (const dir of resolvedRootDirs) {
17846
+ if (!import_fs13.default.existsSync(dir))
17825
17847
  throw new TRPCError({
17826
17848
  code: "BAD_REQUEST",
17827
- message: `Directory does not exist: ${dir2}`
17849
+ message: `Directory does not exist: ${dir}`
17828
17850
  });
17829
17851
  }
17830
- if (!ctx.projectsFilePath)
17831
- throw new TRPCError({
17832
- code: "INTERNAL_SERVER_ERROR",
17833
- message: "No projects file configured"
17834
- });
17852
+ const filePath = requireProjectsFile(ctx.projectsFilePath);
17835
17853
  const entry = {
17836
17854
  id: input.id,
17837
17855
  name: input.name,
@@ -17839,23 +17857,136 @@ var createProject = (t6) => t6.procedure.input(
17839
17857
  docsDirs: resolvedDocsDirs
17840
17858
  };
17841
17859
  if (resolvedRootDirs.length > 0) entry.rootDirs = resolvedRootDirs;
17842
- let fileContents = [];
17843
- try {
17844
- const raw = import_fs13.default.readFileSync(ctx.projectsFilePath, "utf-8");
17845
- const parsed = JSON.parse(raw);
17846
- if (Array.isArray(parsed)) fileContents = parsed;
17847
- } catch {
17848
- }
17860
+ const fileContents = readProjectsFile(filePath);
17849
17861
  fileContents.push(entry);
17850
- const dir = import_path16.default.dirname(ctx.projectsFilePath);
17851
- if (!import_fs13.default.existsSync(dir)) import_fs13.default.mkdirSync(dir, { recursive: true });
17852
- import_fs13.default.writeFileSync(
17853
- ctx.projectsFilePath,
17854
- JSON.stringify(fileContents, null, 2) + "\n",
17855
- "utf-8"
17856
- );
17862
+ writeProjectsFile(filePath, fileContents);
17857
17863
  return { id: input.id, name: input.name, emoji: input.emoji };
17858
17864
  });
17865
+ var renameProject = (t6) => t6.procedure.input(
17866
+ import_v4.z.object({
17867
+ id: import_v4.z.string().trim().min(1),
17868
+ name: import_v4.z.string().trim().min(1).max(200)
17869
+ })
17870
+ ).mutation(({ ctx, input }) => {
17871
+ const filePath = requireProjectsFile(ctx.projectsFilePath);
17872
+ const contents = readProjectsFile(filePath);
17873
+ const entry = contents.find(
17874
+ (p3) => typeof p3 === "object" && p3 !== null && p3.id === input.id
17875
+ );
17876
+ if (!entry)
17877
+ throw new TRPCError({
17878
+ code: "NOT_FOUND",
17879
+ message: `Project "${input.id}" not found`
17880
+ });
17881
+ entry.name = input.name;
17882
+ writeProjectsFile(filePath, contents);
17883
+ return { id: input.id, name: input.name };
17884
+ });
17885
+ var deleteProject = (t6) => t6.procedure.input(import_v4.z.object({ id: import_v4.z.string().trim().min(1) })).mutation(({ ctx, input }) => {
17886
+ const filePath = requireProjectsFile(ctx.projectsFilePath);
17887
+ const contents = readProjectsFile(filePath);
17888
+ const filtered = contents.filter(
17889
+ (p3) => !(typeof p3 === "object" && p3 !== null && p3.id === input.id)
17890
+ );
17891
+ if (filtered.length === contents.length)
17892
+ throw new TRPCError({
17893
+ code: "NOT_FOUND",
17894
+ message: `Project "${input.id}" not found`
17895
+ });
17896
+ writeProjectsFile(filePath, filtered);
17897
+ return { id: input.id };
17898
+ });
17899
+ var getProject = (t6) => t6.procedure.input(import_v4.z.object({ id: import_v4.z.string().trim().min(1) })).query(({ ctx, input }) => {
17900
+ const filePath = requireProjectsFile(ctx.projectsFilePath);
17901
+ const contents = readProjectsFile(filePath);
17902
+ const entry = contents.find(
17903
+ (p3) => typeof p3 === "object" && p3 !== null && p3.id === input.id
17904
+ );
17905
+ if (!entry)
17906
+ throw new TRPCError({
17907
+ code: "NOT_FOUND",
17908
+ message: `Project "${input.id}" not found`
17909
+ });
17910
+ return {
17911
+ id: String(entry.id),
17912
+ name: String(entry.name ?? ""),
17913
+ emoji: typeof entry.emoji === "string" ? entry.emoji : null,
17914
+ docsDirs: Array.isArray(entry.docsDirs) ? entry.docsDirs : [],
17915
+ rootDirs: Array.isArray(entry.rootDirs) ? entry.rootDirs : []
17916
+ };
17917
+ });
17918
+ var updateProjectEntry = (t6) => t6.procedure.input(
17919
+ import_v4.z.object({
17920
+ id: import_v4.z.string().trim().min(1),
17921
+ name: import_v4.z.string().trim().min(1).max(200),
17922
+ emoji: import_v4.z.string().trim().max(10).nullable().optional(),
17923
+ docsDirs: import_v4.z.array(import_v4.z.string().trim().min(1)).min(1),
17924
+ rootDirs: import_v4.z.array(import_v4.z.string().trim().min(1)).optional()
17925
+ })
17926
+ ).mutation(({ ctx, input }) => {
17927
+ const filePath = requireProjectsFile(ctx.projectsFilePath);
17928
+ const contents = readProjectsFile(filePath);
17929
+ const entry = contents.find(
17930
+ (p3) => typeof p3 === "object" && p3 !== null && p3.id === input.id
17931
+ );
17932
+ if (!entry)
17933
+ throw new TRPCError({
17934
+ code: "NOT_FOUND",
17935
+ message: `Project "${input.id}" not found`
17936
+ });
17937
+ const resolvedDocsDirs = input.docsDirs.map((d3) => import_path16.default.resolve(d3));
17938
+ const resolvedRootDirs = (input.rootDirs ?? []).map(
17939
+ (d3) => import_path16.default.resolve(d3)
17940
+ );
17941
+ for (const dir of resolvedDocsDirs) {
17942
+ if (!import_fs13.default.existsSync(dir))
17943
+ throw new TRPCError({
17944
+ code: "BAD_REQUEST",
17945
+ message: `Directory does not exist: ${dir}`
17946
+ });
17947
+ }
17948
+ for (const dir of resolvedRootDirs) {
17949
+ if (!import_fs13.default.existsSync(dir))
17950
+ throw new TRPCError({
17951
+ code: "BAD_REQUEST",
17952
+ message: `Directory does not exist: ${dir}`
17953
+ });
17954
+ }
17955
+ entry.name = input.name;
17956
+ entry.emoji = input.emoji ?? null;
17957
+ entry.docsDirs = resolvedDocsDirs;
17958
+ if (resolvedRootDirs.length > 0) entry.rootDirs = resolvedRootDirs;
17959
+ else delete entry.rootDirs;
17960
+ writeProjectsFile(filePath, contents);
17961
+ return {
17962
+ id: input.id,
17963
+ name: input.name,
17964
+ emoji: input.emoji ?? null
17965
+ };
17966
+ });
17967
+ var reorderProjects = (t6) => t6.procedure.input(import_v4.z.object({ ids: import_v4.z.array(import_v4.z.string().trim().min(1)).min(1) })).mutation(({ ctx, input }) => {
17968
+ const filePath = requireProjectsFile(ctx.projectsFilePath);
17969
+ const contents = readProjectsFile(filePath);
17970
+ const byId = /* @__PURE__ */ new Map();
17971
+ for (const entry of contents) {
17972
+ if (typeof entry === "object" && entry !== null)
17973
+ byId.set(entry.id, entry);
17974
+ }
17975
+ const reordered = [];
17976
+ for (const id of input.ids) {
17977
+ const entry = byId.get(id);
17978
+ if (!entry)
17979
+ throw new TRPCError({
17980
+ code: "NOT_FOUND",
17981
+ message: `Project "${id}" not found`
17982
+ });
17983
+ reordered.push(entry);
17984
+ byId.delete(id);
17985
+ }
17986
+ for (const remaining of byId.values()) reordered.push(remaining);
17987
+ writeProjectsFile(filePath, reordered);
17988
+ return { ids: input.ids };
17989
+ });
17859
17990
 
17860
17991
  // ../../packages/trpc/src/procedures/project.ts
17861
17992
  var import_v42 = require("zod/v4");
@@ -18394,7 +18525,12 @@ var createTrpcRouter = (t6) => t6.router({
18394
18525
  }),
18395
18526
  projects: t6.router({
18396
18527
  list: listProjects(t6),
18397
- create: createProject(t6)
18528
+ get: getProject(t6),
18529
+ create: createProject(t6),
18530
+ update: updateProjectEntry(t6),
18531
+ rename: renameProject(t6),
18532
+ delete: deleteProject(t6),
18533
+ reorder: reorderProjects(t6)
18398
18534
  }),
18399
18535
  project: t6.router({
18400
18536
  get: getProjectConfig(t6),
@@ -18507,7 +18643,7 @@ var ServerCommand = class {
18507
18643
  // package.json
18508
18644
  var package_default = {
18509
18645
  name: "@maplab/hyperdoc",
18510
- version: "0.3.0",
18646
+ version: "0.4.0",
18511
18647
  description: "Hyperdoc CLI and local server",
18512
18648
  type: "commonjs",
18513
18649
  main: "dist/index.js",