@ricsam/r5d-worker 0.0.36 → 0.0.38

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.
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var managed_paths_exports = {};
30
+ __export(managed_paths_exports, {
31
+ BRANCH_NAME_MAX_LENGTH: () => BRANCH_NAME_MAX_LENGTH,
32
+ BRANCH_NAME_PATTERN: () => BRANCH_NAME_PATTERN,
33
+ assertPathInside: () => assertPathInside,
34
+ legacyProjectSlug: () => legacyProjectSlug,
35
+ managedBranchPath: () => managedBranchPath,
36
+ managedProjectRoot: () => managedProjectRoot,
37
+ migrateLegacyProjectRoots: () => migrateLegacyProjectRoots,
38
+ validateCheckoutPathSegments: () => validateCheckoutPathSegments,
39
+ validateManagedBranchName: () => validateManagedBranchName
40
+ });
41
+ module.exports = __toCommonJS(managed_paths_exports);
42
+ var import_node_fs = __toESM(require("node:fs"), 1);
43
+ var import_node_path = __toESM(require("node:path"), 1);
44
+ const BRANCH_NAME_MAX_LENGTH = 45;
45
+ const BRANCH_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*(?:\/[a-z0-9]+(?:-[a-z0-9]+)*)*$/;
46
+ const PROJECT_SEGMENT_PATTERN = /^[a-z0-9._-]+$/;
47
+ const WINDOWS_RESERVED_PATH_SEGMENT = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\..*)?$/i;
48
+ function validateManagedBranchName(branchName) {
49
+ if (typeof branchName !== "string" || branchName.length === 0) {
50
+ throw new Error("Branch name is required");
51
+ }
52
+ if (branchName.length > BRANCH_NAME_MAX_LENGTH) {
53
+ throw new Error(`Branch name must be ${BRANCH_NAME_MAX_LENGTH} characters or fewer`);
54
+ }
55
+ if (!BRANCH_NAME_PATTERN.test(branchName)) {
56
+ throw new Error(`Invalid branch name from server: ${branchName}`);
57
+ }
58
+ const reserved = branchName.split("/").find((segment) => WINDOWS_RESERVED_PATH_SEGMENT.test(segment));
59
+ if (reserved) {
60
+ throw new Error(`Invalid branch name from server: reserved path segment '${reserved}'`);
61
+ }
62
+ }
63
+ function validateCheckoutPathSegments(value) {
64
+ if (!Array.isArray(value) || value.length !== 2) {
65
+ throw new Error("Invalid checkout path from server: expected namespace and project segments");
66
+ }
67
+ const segments = value;
68
+ for (const segment of segments) {
69
+ if (typeof segment !== "string" || !PROJECT_SEGMENT_PATTERN.test(segment) || segment !== segment.toLowerCase() || segment === "." || segment === ".." || segment === ".git" || segment.endsWith(".") || WINDOWS_RESERVED_PATH_SEGMENT.test(segment)) {
70
+ throw new Error(`Invalid checkout path segment from server: ${String(segment)}`);
71
+ }
72
+ }
73
+ return [segments[0], segments[1]];
74
+ }
75
+ function assertPathInside(root, candidate, label) {
76
+ const resolvedRoot = import_node_path.default.resolve(root);
77
+ const resolvedCandidate = import_node_path.default.resolve(candidate);
78
+ const relative = import_node_path.default.relative(resolvedRoot, resolvedCandidate);
79
+ if (relative === ".." || relative.startsWith(`..${import_node_path.default.sep}`) || import_node_path.default.isAbsolute(relative)) {
80
+ throw new Error(`${label} escapes its managed root: ${candidate}`);
81
+ }
82
+ }
83
+ function assertNoSymlinkComponents(root, candidate) {
84
+ assertPathInside(root, candidate, "Checkout path");
85
+ const relative = import_node_path.default.relative(import_node_path.default.resolve(root), import_node_path.default.resolve(candidate));
86
+ let current = import_node_path.default.resolve(root);
87
+ for (const component of relative.split(import_node_path.default.sep).filter(Boolean)) {
88
+ current = import_node_path.default.join(current, component);
89
+ if (!import_node_fs.default.existsSync(current)) break;
90
+ if (import_node_fs.default.lstatSync(current).isSymbolicLink()) {
91
+ throw new Error(`Checkout path contains a symbolic link: ${current}`);
92
+ }
93
+ }
94
+ }
95
+ function managedProjectRoot(projectsRoot, checkoutPathSegments) {
96
+ const segments = validateCheckoutPathSegments(checkoutPathSegments);
97
+ const result = import_node_path.default.join(projectsRoot, ...segments);
98
+ assertNoSymlinkComponents(projectsRoot, result);
99
+ return result;
100
+ }
101
+ function managedBranchPath(projectsRoot, checkoutPathSegments, branchName) {
102
+ validateManagedBranchName(branchName);
103
+ const projectRoot = managedProjectRoot(projectsRoot, checkoutPathSegments);
104
+ const result = import_node_path.default.join(projectRoot, ...branchName.split("/"));
105
+ assertNoSymlinkComponents(projectRoot, result);
106
+ return result;
107
+ }
108
+ function legacyProjectSlug(projectPath, projectId) {
109
+ return (projectPath || projectId).trim().toLowerCase().replace(/[^a-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "") || projectId;
110
+ }
111
+ function migrateLegacyProjectRoots(projectsRoot, projects) {
112
+ const resolvedRoot = import_node_path.default.resolve(projectsRoot);
113
+ const legacyOwners = /* @__PURE__ */ new Map();
114
+ const nestedOwners = /* @__PURE__ */ new Map();
115
+ const moves = [];
116
+ for (const project of projects) {
117
+ const nestedRoot = managedProjectRoot(resolvedRoot, project.checkoutPathSegments);
118
+ const legacySlug = legacyProjectSlug(project.projectPath, project.projectId);
119
+ const legacyRoot = import_node_path.default.join(resolvedRoot, legacySlug);
120
+ assertNoSymlinkComponents(resolvedRoot, legacyRoot);
121
+ const existingLegacyOwner = legacyOwners.get(legacyRoot);
122
+ if (existingLegacyOwner) {
123
+ throw new Error(`Projects ${existingLegacyOwner} and ${project.projectId} collide at legacy checkout path '${legacyRoot}'`);
124
+ }
125
+ legacyOwners.set(legacyRoot, project.projectId);
126
+ const existingNestedOwner = nestedOwners.get(nestedRoot);
127
+ if (existingNestedOwner) {
128
+ throw new Error(`Projects ${existingNestedOwner} and ${project.projectId} collide at checkout path '${nestedRoot}'`);
129
+ }
130
+ nestedOwners.set(nestedRoot, project.projectId);
131
+ const legacyExists = import_node_fs.default.existsSync(legacyRoot);
132
+ const nestedExists = import_node_fs.default.existsSync(nestedRoot);
133
+ if (legacyExists && nestedExists) {
134
+ throw new Error(
135
+ `Checkout migration is ambiguous for ${project.projectPath}: both '${legacyRoot}' and '${nestedRoot}' exist. Preserve the desired checkout and remove or relocate the other path before reconnecting the worker.`
136
+ );
137
+ }
138
+ if (legacyExists) moves.push({ projectId: project.projectId, legacyRoot, nestedRoot });
139
+ }
140
+ for (const move of moves) {
141
+ import_node_fs.default.mkdirSync(import_node_path.default.dirname(move.nestedRoot), { recursive: true });
142
+ assertNoSymlinkComponents(resolvedRoot, import_node_path.default.dirname(move.nestedRoot));
143
+ import_node_fs.default.renameSync(move.legacyRoot, move.nestedRoot);
144
+ }
145
+ return moves.map((move) => move.projectId);
146
+ }
147
+ // Annotate the CommonJS export names for ESM import in node:
148
+ 0 && (module.exports = {
149
+ BRANCH_NAME_MAX_LENGTH,
150
+ BRANCH_NAME_PATTERN,
151
+ assertPathInside,
152
+ legacyProjectSlug,
153
+ managedBranchPath,
154
+ managedProjectRoot,
155
+ migrateLegacyProjectRoots,
156
+ validateCheckoutPathSegments,
157
+ validateManagedBranchName
158
+ });
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/r5d-worker",
3
- "version": "0.0.36",
3
+ "version": "0.0.38",
4
4
  "type": "commonjs"
5
5
  }