@micacms/runtime 0.4.1 → 0.5.0-rc.2
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/README.md +2 -2
- package/dist/app.d.ts +8 -37
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +7 -42
- package/dist/app.js.map +1 -1
- package/dist/config.d.ts +12 -82
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +14 -82
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +37 -66
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +24 -75
- package/dist/context.js.map +1 -1
- package/dist/http.d.ts +8 -16
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +6 -13
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +13 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -14
- package/dist/index.js.map +1 -1
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/file-type.js.map +1 -1
- package/dist/lib/id.js.map +1 -1
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/ports.js.map +1 -1
- package/dist/lib/rate-limit.js.map +1 -1
- package/dist/lib/schema-stats.js.map +1 -1
- package/dist/lib/version.js.map +1 -1
- package/dist/middleware/index.js.map +1 -1
- package/dist/routes/admin-content.d.ts +4 -17
- package/dist/routes/admin-content.d.ts.map +1 -1
- package/dist/routes/admin-content.js +11 -51
- package/dist/routes/admin-content.js.map +1 -1
- package/dist/routes/admin-media.d.ts +3 -14
- package/dist/routes/admin-media.d.ts.map +1 -1
- package/dist/routes/admin-media.js +7 -29
- package/dist/routes/admin-media.js.map +1 -1
- package/dist/routes/admin-spa.js.map +1 -1
- package/dist/routes/admin-staging.d.ts +4 -9
- package/dist/routes/admin-staging.d.ts.map +1 -1
- package/dist/routes/admin-staging.js +31 -18
- package/dist/routes/admin-staging.js.map +1 -1
- package/dist/routes/admin-system.d.ts +2 -8
- package/dist/routes/admin-system.d.ts.map +1 -1
- package/dist/routes/admin-system.js +9 -44
- package/dist/routes/admin-system.js.map +1 -1
- package/dist/routes/health.d.ts +3 -10
- package/dist/routes/health.d.ts.map +1 -1
- package/dist/routes/health.js +9 -26
- package/dist/routes/health.js.map +1 -1
- package/dist/schema.d.ts +10 -38
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +14 -65
- package/dist/schema.js.map +1 -1
- package/dist/server.d.ts +2 -10
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +3 -9
- package/dist/server.js.map +1 -1
- package/dist/services/changes.d.ts +150 -0
- package/dist/services/changes.d.ts.map +1 -0
- package/dist/services/changes.js +339 -0
- package/dist/services/changes.js.map +1 -0
- package/dist/services/content-store.d.ts +61 -0
- package/dist/services/content-store.d.ts.map +1 -0
- package/dist/services/content-store.js +330 -0
- package/dist/services/content-store.js.map +1 -0
- package/dist/services/media.d.ts +9 -29
- package/dist/services/media.d.ts.map +1 -1
- package/dist/services/media.js +17 -57
- package/dist/services/media.js.map +1 -1
- package/dist/services/staging.d.ts +35 -167
- package/dist/services/staging.d.ts.map +1 -1
- package/dist/services/staging.js +195 -458
- package/dist/services/staging.js.map +1 -1
- package/dist/workspace/developer.d.ts +14 -0
- package/dist/workspace/developer.d.ts.map +1 -0
- package/dist/workspace/developer.js +31 -0
- package/dist/workspace/developer.js.map +1 -0
- package/dist/workspace/files.d.ts +70 -0
- package/dist/workspace/files.d.ts.map +1 -0
- package/dist/workspace/files.js +176 -0
- package/dist/workspace/files.js.map +1 -0
- package/dist/workspace/git.d.ts +45 -0
- package/dist/workspace/git.d.ts.map +1 -0
- package/dist/workspace/git.js +68 -0
- package/dist/workspace/git.js.map +1 -0
- package/dist/workspace/locks.d.ts +33 -0
- package/dist/workspace/locks.d.ts.map +1 -0
- package/dist/workspace/locks.js +76 -0
- package/dist/workspace/locks.js.map +1 -0
- package/dist/workspace/policy.d.ts +92 -0
- package/dist/workspace/policy.d.ts.map +1 -0
- package/dist/workspace/policy.js +7 -0
- package/dist/workspace/policy.js.map +1 -0
- package/dist/workspace/tree.d.ts +73 -0
- package/dist/workspace/tree.d.ts.map +1 -0
- package/dist/workspace/tree.js +229 -0
- package/dist/workspace/tree.js.map +1 -0
- package/package.json +2 -3
- package/dist/db/driver.d.ts +0 -35
- package/dist/db/driver.d.ts.map +0 -1
- package/dist/db/driver.js +0 -95
- package/dist/db/driver.js.map +0 -1
- package/dist/lib/git.d.ts +0 -29
- package/dist/lib/git.d.ts.map +0 -1
- package/dist/lib/git.js +0 -62
- package/dist/lib/git.js.map +0 -1
- package/dist/services/staging-local.d.ts +0 -58
- package/dist/services/staging-local.d.ts.map +0 -1
- package/dist/services/staging-local.js +0 -391
- package/dist/services/staging-local.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"staging.js","sourceRoot":"","sources":["../../src/services/staging.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"staging.js","sourceRoot":"","sources":["../../src/services/staging.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The staging service on a Git working tree. Autosave has already written the\n * files; Publish commits the reviewed paths.\n *\n * - Every Git operation is limited to an explicit path set, so other work in\n * the same checkout is never swept in.\n * - Only the reviewed files are published, as the editor saw them. Drafts of\n * other entries stay drafts.\n * - When the push fails, the commit stays as `committed-pending-push`; a\n * retry pushes and never commits again.\n */\n\nimport { MANIFEST_PATH, memorySource, type PublishResult, type Site } from \"@micacms/core\";\n\nimport { ApiError, badRequest, notFound } from \"../lib/errors.js\";\nimport type { Logger } from \"../lib/logger.js\";\nimport { developerPolicy } from \"../workspace/developer.js\";\nimport type { ContentFiles } from \"../workspace/files.js\";\nimport { GitError } from \"../workspace/git.js\";\nimport { createWorkspaceLocks, type WorkspaceLocks } from \"../workspace/locks.js\";\nimport type { OwnerPolicy } from \"../workspace/policy.js\";\nimport {\n aheadOfUpstream,\n commitPaths,\n currentBranch,\n discardChange,\n headRevision,\n headSource,\n listTreeChanges,\n locateTree,\n type GitTree,\n type TreeChange,\n} from \"../workspace/tree.js\";\nimport {\n analyseChanges,\n compareSources,\n describeProblems,\n flattenProblems,\n type AnnotatedChange,\n type CompareTarget,\n type Comparison,\n type ContentStagingService,\n type PublishInput,\n type RepositoryInfo,\n type StagingStatus,\n type StagingValidation,\n} from \"./changes.js\";\n\nexport interface WorkingTreeStagingDeps {\n model: Site;\n /**\n * The working tree's files without the lock wrapper: this service holds the\n * locks around whole operations.\n */\n files: ContentFiles;\n contentRoot: string;\n schemaRevision: string | null;\n /** `MICA_LOCAL_PUBLISH`, for the default developer policy. */\n publishEnabled: boolean;\n logger: Logger;\n /** Defaults to the developer. */\n policy?: OwnerPolicy;\n /** Shared with the services that write content. */\n locks?: WorkspaceLocks;\n /**\n * Set by a managed clone, whose Git runs in an isolated environment. Without\n * it, the developer's Git finds the tree.\n */\n tree?: GitTree;\n}\n\nexport function createWorkingTreeStagingService(\n deps: WorkingTreeStagingDeps,\n): ContentStagingService {\n const { model, files, contentRoot, logger } = deps;\n const policy = deps.policy ?? developerPolicy({ publishEnabled: deps.publishEnabled, logger });\n const locks = deps.locks ?? createWorkspaceLocks();\n\n const analyse = async (tree: GitTree, treeChanges: TreeChange[]) => {\n const { changes, validation } = await analyseChanges(\n model,\n files,\n treeChanges,\n headSource(tree),\n );\n\n // The field validator cannot see a merge conflict: the file holds Git's conflict format.\n for (const change of treeChanges) {\n if (!change.conflicted) continue;\n validation.problems.push({\n path: change.path,\n label: change.path,\n issues: [\n { path: \"\", message: \"This file has a Git merge conflict. Resolve it with your Git tools.\" },\n ],\n });\n }\n validation.ok = validation.problems.length === 0;\n\n return { changes, validation };\n };\n\n const locate = async (): Promise<GitTree | { reason: string }> => deps.tree ?? locateTree(contentRoot);\n\n const located = async (): Promise<GitTree> => {\n const tree = await locate();\n if (\"reason\" in tree) throw badRequest(tree.reason);\n return tree;\n };\n\n const publishable = async (): Promise<GitTree> => {\n const availability = policy.publishAvailability();\n if (!availability.enabled) throw badRequest(availability.reason);\n return located();\n };\n\n /** The key that keeps an entry's files together: a publication never splits one. */\n const groupOf = (change: AnnotatedChange): string => {\n const owner = change.owner;\n if (owner.kind === \"entry\") return `entry:${owner.collection}/${owner.slug}`;\n if (owner.kind === \"singleton\") return `singleton:${owner.name}`;\n if (owner.kind === \"order\") return `order:${owner.collection}`;\n return `file:${change.path}`;\n };\n\n const withRevisions = async (changes: AnnotatedChange[]): Promise<AnnotatedChange[]> =>\n Promise.all(\n changes.map(async (change) => ({\n ...change,\n revision: change.kind === \"delete\" ? null : await files.revision(change.path),\n })),\n );\n\n /** Refused for the developer's checkout: Mica never fetches or merges there. */\n const managedOnly = <T>(action: T | undefined): T => {\n if (action === undefined) throw notFound(\"This is the developer's checkout; Git there is theirs.\");\n return action;\n };\n\n return {\n async status(): Promise<StagingStatus> {\n const tree = await locate();\n const sync = policy.syncStatus?.() ?? null;\n\n if (\"reason\" in tree) {\n return {\n owner: policy.owner,\n publish: { enabled: false, reason: tree.reason },\n head: null,\n branch: null,\n ahead: null,\n changes: [],\n validation: emptyValidation(),\n sync,\n };\n }\n\n const { changes, validation, head, branch } = await locks.tree.read(async () => {\n const analysed = await analyse(tree, await listTreeChanges(tree));\n return {\n ...analysed,\n changes: await withRevisions(analysed.changes),\n head: await headRevision(tree),\n branch: await currentBranch(tree),\n };\n });\n\n return {\n owner: policy.owner,\n publish: policy.publishAvailability(),\n head,\n branch,\n ahead: await aheadOfUpstream(tree),\n changes,\n validation,\n sync,\n };\n },\n\n async publish(input: PublishInput): Promise<PublishResult> {\n const message = input.message.trim();\n if (!message) throw badRequest(\"A publication needs a commit message.\");\n const reviewed = Object.keys(input.paths);\n if (reviewed.length === 0) throw badRequest(\"Choose at least one change to publish.\");\n\n const tree = await publishable();\n\n // One publication at a time from sync to push: no sync can run in\n // between, and no second commit can stack up.\n return locks.remote.run(async () => {\n await policy.prepare(tree);\n\n const revision = await locks.tree.write(async () => {\n const pending = await withRevisions((await analyse(tree, await listTreeChanges(tree))).changes);\n const byPath = new Map(pending.map((change) => [change.path, change]));\n\n // The review gate refuses a file saved again since the review, a\n // reviewed file that is no longer pending, or another file of a\n // reviewed entry. Drafts of other entries never block a publication.\n const reviewedGroups = new Set(\n reviewed.map((path) => byPath.get(path)).flatMap((change) => (change ? [groupOf(change)] : [])),\n );\n const stale = [\n ...reviewed.filter((path) => byPath.get(path)?.revision !== input.paths[path] || !byPath.has(path)),\n ...pending\n .filter((change) => reviewedGroups.has(groupOf(change)) && !(change.path in input.paths))\n .map((change) => change.path),\n ];\n if (stale.length > 0) {\n throw new ApiError(\n \"conflict\",\n \"Some of these changes were edited after you reviewed them. Review them again, then publish.\",\n );\n }\n\n // The model drift gate: validation used the model that this process started with.\n if ((await files.revision(MANIFEST_PATH)) !== deps.schemaRevision) {\n throw new ApiError(\n \"conflict\",\n \"The content model changed after this server started. Restart Mica to load \" +\n \"the new model, then review the pending changes and publish again.\",\n );\n }\n\n const selected = (await listTreeChanges(tree)).filter((change) => change.path in input.paths);\n const { validation } = await analyse(tree, selected);\n if (!validation.ok) {\n throw new ApiError(\"validation_failed\", describeProblems(validation.problems), {\n issues: flattenProblems(validation.problems),\n });\n }\n\n try {\n const revision = await commitPaths(tree, reviewed, message, policy.commitAuthor(input.author));\n logger.info(\"Published\", { revision, files: reviewed.length, owner: policy.owner });\n return revision;\n } catch (error) {\n if (error instanceof GitError) {\n // Git's message is the actionable part: no identity, a hook that\n // refused, a rebase in progress.\n throw new ApiError(\"conflict\", `Git refused the commit: ${error.message}`);\n }\n throw error;\n }\n });\n\n return policy.push(tree, revision);\n });\n },\n\n async push(): Promise<PublishResult> {\n const tree = await publishable();\n\n return locks.remote.run(async () => {\n const revision = await headRevision(tree);\n if (revision === null) throw badRequest(\"There is no commit to push yet.\");\n return policy.push(tree, revision);\n });\n },\n\n async discard(requested: string[]): Promise<{ discarded: string[] }> {\n const tree = await located();\n\n return locks.tree.write(async () => {\n // Discard is destructive, so it reaches only paths that the change list names.\n const current = new Map((await listTreeChanges(tree)).map((change) => [change.path, change]));\n\n const discarded: string[] = [];\n for (const path of requested) {\n const change = current.get(path);\n if (!change) continue;\n await discardChange(tree, change);\n discarded.push(path);\n }\n\n return { discarded };\n });\n },\n\n async compare(target: CompareTarget, against: \"head\" | \"origin\" = \"head\"): Promise<Comparison> {\n const tree = await locate();\n if (against === \"origin\" && !policy.upstreamRef) throw badRequest(\"There is no website version to compare with here.\");\n // Without a repository nothing is published, so \"before\" is an empty source.\n const published =\n \"reason\" in tree\n ? memorySource({}, \"unpublished\")\n : headSource(tree, against === \"origin\" ? policy.upstreamRef : \"HEAD\");\n return locks.tree.read(() => compareSources(model, published, files, target));\n },\n\n async sync(): Promise<void> {\n await managedOnly(policy.sync)();\n },\n\n async resolve(group: string, choice: \"mine\" | \"website\"): Promise<void> {\n await managedOnly(policy.resolve)(group, choice);\n },\n\n async repository(): Promise<RepositoryInfo> {\n const tree = await locate();\n const described = (await policy.describe?.()) ?? null;\n return {\n owner: policy.owner,\n branch: \"reason\" in tree ? null : await currentBranch(tree),\n head: \"reason\" in tree ? null : await headRevision(tree),\n url: described?.url ?? null,\n cloneBytes: described?.cloneBytes ?? null,\n sync: policy.syncStatus?.() ?? null,\n };\n },\n };\n}\n\nfunction emptyValidation(): StagingValidation {\n return { ok: true, problems: [] };\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The policy for the developer's own checkout. Mica never fetches, merges or
|
|
3
|
+
* resets here. Publish pushes with the developer's `git`, credentials and
|
|
4
|
+
* upstream; a failed push keeps the commit.
|
|
5
|
+
*/
|
|
6
|
+
import type { Logger } from "../lib/logger.js";
|
|
7
|
+
import type { OwnerPolicy } from "./policy.js";
|
|
8
|
+
export interface DeveloperPolicyOptions {
|
|
9
|
+
/** `MICA_LOCAL_PUBLISH`. */
|
|
10
|
+
publishEnabled: boolean;
|
|
11
|
+
logger: Logger;
|
|
12
|
+
}
|
|
13
|
+
export declare function developerPolicy(options: DeveloperPolicyOptions): OwnerPolicy;
|
|
14
|
+
//# sourceMappingURL=developer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"developer.d.ts","sourceRoot":"","sources":["../../src/workspace/developer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,KAAK,EAAE,WAAW,EAAuB,MAAM,aAAa,CAAC;AAGpE,MAAM,WAAW,sBAAsB;IACrC,4BAA4B;IAC5B,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,WAAW,CA0B5E"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The policy for the developer's own checkout. Mica never fetches, merges or
|
|
3
|
+
* resets here. Publish pushes with the developer's `git`, credentials and
|
|
4
|
+
* upstream; a failed push keeps the commit.
|
|
5
|
+
*/
|
|
6
|
+
import { GitError } from "./git.js";
|
|
7
|
+
export function developerPolicy(options) {
|
|
8
|
+
return {
|
|
9
|
+
owner: "developer",
|
|
10
|
+
publishAvailability() {
|
|
11
|
+
return options.publishEnabled
|
|
12
|
+
? { enabled: true }
|
|
13
|
+
: { enabled: false, reason: "Publishing from local mode is disabled (MICA_LOCAL_PUBLISH=false)." };
|
|
14
|
+
},
|
|
15
|
+
async prepare() { },
|
|
16
|
+
// The commit keeps the developer's own Git identity.
|
|
17
|
+
commitAuthor: () => undefined,
|
|
18
|
+
async push(tree, revision) {
|
|
19
|
+
try {
|
|
20
|
+
await tree.git.run(["push"]);
|
|
21
|
+
return { state: "published", revision };
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
const pushError = error instanceof GitError ? error.message : String(error);
|
|
25
|
+
options.logger.warn("Publish committed but the push failed", { revision, pushError });
|
|
26
|
+
return { state: "committed-pending-push", revision, pushError };
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=developer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"developer.js","sourceRoot":"","sources":["../../src/workspace/developer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAUpC,MAAM,UAAU,eAAe,CAAC,OAA+B;IAC7D,OAAO;QACL,KAAK,EAAE,WAAW;QAElB,mBAAmB;YACjB,OAAO,OAAO,CAAC,cAAc;gBAC3B,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE;gBACnB,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,oEAAoE,EAAE,CAAC;QACvG,CAAC;QAED,KAAK,CAAC,OAAO,KAAI,CAAC;QAElB,qDAAqD;QACrD,YAAY,EAAE,GAAG,EAAE,CAAC,SAAS;QAE7B,KAAK,CAAC,IAAI,CAAC,IAAa,EAAE,QAAgB;YACxC,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC7B,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;YAC1C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,SAAS,GAAG,KAAK,YAAY,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC5E,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,uCAAuC,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;gBACtF,OAAO,EAAE,KAAK,EAAE,wBAAwB,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;YAClE,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["/**\n * The policy for the developer's own checkout. Mica never fetches, merges or\n * resets here. Publish pushes with the developer's `git`, credentials and\n * upstream; a failed push keeps the commit.\n */\n\nimport type { PublishResult } from \"@micacms/core\";\n\nimport type { Logger } from \"../lib/logger.js\";\nimport { GitError } from \"./git.js\";\nimport type { OwnerPolicy, PublishAvailability } from \"./policy.js\";\nimport type { GitTree } from \"./tree.js\";\n\nexport interface DeveloperPolicyOptions {\n /** `MICA_LOCAL_PUBLISH`. */\n publishEnabled: boolean;\n logger: Logger;\n}\n\nexport function developerPolicy(options: DeveloperPolicyOptions): OwnerPolicy {\n return {\n owner: \"developer\",\n\n publishAvailability(): PublishAvailability {\n return options.publishEnabled\n ? { enabled: true }\n : { enabled: false, reason: \"Publishing from local mode is disabled (MICA_LOCAL_PUBLISH=false).\" };\n },\n\n async prepare() {},\n\n // The commit keeps the developer's own Git identity.\n commitAuthor: () => undefined,\n\n async push(tree: GitTree, revision: string): Promise<PublishResult> {\n try {\n await tree.git.run([\"push\"]);\n return { state: \"published\", revision };\n } catch (error) {\n const pushError = error instanceof GitError ? error.message : String(error);\n options.logger.warn(\"Publish committed but the push failed\", { revision, pushError });\n return { state: \"committed-pending-push\", revision, pushError };\n }\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The content files of a working tree: the port everything reads and saves
|
|
3
|
+
* through, and its implementation. It extends `ContentSource`, so the Astro
|
|
4
|
+
* build and Mica share the same content reading code. `apply` is atomic: an
|
|
5
|
+
* entry is several files, and half of one is corruption.
|
|
6
|
+
*/
|
|
7
|
+
import { type ContentSource } from "@micacms/core";
|
|
8
|
+
export declare class FilesError extends Error {
|
|
9
|
+
name: string;
|
|
10
|
+
}
|
|
11
|
+
/** A file changed under an editor. The editor can recover: reload and apply again. */
|
|
12
|
+
export declare class ConflictError extends FilesError {
|
|
13
|
+
/** Paths whose revision no longer matched. */
|
|
14
|
+
readonly paths: string[];
|
|
15
|
+
name: string;
|
|
16
|
+
constructor(message: string,
|
|
17
|
+
/** Paths whose revision no longer matched. */
|
|
18
|
+
paths: string[]);
|
|
19
|
+
}
|
|
20
|
+
/** Who a commit names. */
|
|
21
|
+
export interface Author {
|
|
22
|
+
name: string;
|
|
23
|
+
email: string;
|
|
24
|
+
}
|
|
25
|
+
export type FileChange = {
|
|
26
|
+
type: "write";
|
|
27
|
+
path: string;
|
|
28
|
+
contents: string | Uint8Array;
|
|
29
|
+
} | {
|
|
30
|
+
type: "delete";
|
|
31
|
+
path: string;
|
|
32
|
+
}
|
|
33
|
+
/** Deletes every file under `path`. Removing an entry removes its directory. */
|
|
34
|
+
| {
|
|
35
|
+
type: "deleteTree";
|
|
36
|
+
path: string;
|
|
37
|
+
};
|
|
38
|
+
export interface FileChanges {
|
|
39
|
+
changes: FileChange[];
|
|
40
|
+
/**
|
|
41
|
+
* Revisions the edit was based on, per path, so editors of different entries
|
|
42
|
+
* never block each other. Null asserts that the path does not exist. Omitted,
|
|
43
|
+
* the write is unconditional.
|
|
44
|
+
*/
|
|
45
|
+
expect?: Record<string, string | null>;
|
|
46
|
+
}
|
|
47
|
+
export interface ContentFiles extends ContentSource {
|
|
48
|
+
/** Bytes of a file, for media. Null when there is no such file. */
|
|
49
|
+
readBinary(path: string): Promise<Uint8Array | null>;
|
|
50
|
+
/**
|
|
51
|
+
* An opaque token for the current state of `path`, or null when it is absent.
|
|
52
|
+
* Compare only for equality.
|
|
53
|
+
*/
|
|
54
|
+
revision(path: string): Promise<string | null>;
|
|
55
|
+
/**
|
|
56
|
+
* Applies every change, or none of them. Throws `ConflictError` when any
|
|
57
|
+
* `expect` no longer holds.
|
|
58
|
+
*/
|
|
59
|
+
apply(input: FileChanges): Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Refuses, before any write, a change or expectation that names the content
|
|
63
|
+
* root or a path outside it.
|
|
64
|
+
*/
|
|
65
|
+
export declare function checkChangePaths(input: FileChanges): void;
|
|
66
|
+
export interface ContentFilesOptions {
|
|
67
|
+
root: string;
|
|
68
|
+
}
|
|
69
|
+
export declare function contentFiles(options: ContentFilesOptions): ContentFiles;
|
|
70
|
+
//# sourceMappingURL=files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/workspace/files.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAAe,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAGhE,qBAAa,UAAW,SAAQ,KAAK;IAC1B,IAAI,SAAgB;CAC9B;AAED,sFAAsF;AACtF,qBAAa,aAAc,SAAQ,UAAU;IAIzC,8CAA8C;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE;IAJjB,IAAI,SAAmB;gBAE9B,OAAO,EAAE,MAAM;IACf,8CAA8C;IACrC,KAAK,EAAE,MAAM,EAAE;CAI3B;AAED,0BAA0B;AAC1B,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAA;CAAE,GAC9D;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAClC,gFAAgF;GAC9E;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,YAAa,SAAQ,aAAa;IACjD,mEAAmE;IACnE,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAErD;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAE/C;;;OAGG;IACH,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAGzD;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,YAAY,CAsHvE"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The content files of a working tree: the port everything reads and saves
|
|
3
|
+
* through, and its implementation. It extends `ContentSource`, so the Astro
|
|
4
|
+
* build and Mica share the same content reading code. `apply` is atomic: an
|
|
5
|
+
* entry is several files, and half of one is corruption.
|
|
6
|
+
*/
|
|
7
|
+
import { createHash } from "node:crypto";
|
|
8
|
+
import { mkdir, readFile, readdir, rename, rm, unlink, writeFile } from "node:fs/promises";
|
|
9
|
+
import { dirname, resolve } from "node:path";
|
|
10
|
+
import { contentPath } from "@micacms/core";
|
|
11
|
+
import { isMissing, within } from "@micacms/core/node";
|
|
12
|
+
export class FilesError extends Error {
|
|
13
|
+
name = "FilesError";
|
|
14
|
+
}
|
|
15
|
+
/** A file changed under an editor. The editor can recover: reload and apply again. */
|
|
16
|
+
export class ConflictError extends FilesError {
|
|
17
|
+
paths;
|
|
18
|
+
name = "ConflictError";
|
|
19
|
+
constructor(message,
|
|
20
|
+
/** Paths whose revision no longer matched. */
|
|
21
|
+
paths) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.paths = paths;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Refuses, before any write, a change or expectation that names the content
|
|
28
|
+
* root or a path outside it.
|
|
29
|
+
*/
|
|
30
|
+
export function checkChangePaths(input) {
|
|
31
|
+
for (const change of input.changes)
|
|
32
|
+
contentPath(change.path);
|
|
33
|
+
for (const path of Object.keys(input.expect ?? {}))
|
|
34
|
+
contentPath(path);
|
|
35
|
+
}
|
|
36
|
+
export function contentFiles(options) {
|
|
37
|
+
const base = resolve(options.root);
|
|
38
|
+
const full = (path, allowRoot = false) => within(base, path, { allowRoot });
|
|
39
|
+
const readBytes = async (path) => {
|
|
40
|
+
try {
|
|
41
|
+
return await readFile(full(path));
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
if (isMissing(error))
|
|
45
|
+
return null;
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
return {
|
|
50
|
+
origin: base,
|
|
51
|
+
async read(path) {
|
|
52
|
+
const bytes = await readBytes(path);
|
|
53
|
+
return bytes === null ? null : Buffer.from(bytes).toString("utf8");
|
|
54
|
+
},
|
|
55
|
+
readBinary: readBytes,
|
|
56
|
+
async list(path) {
|
|
57
|
+
let items;
|
|
58
|
+
try {
|
|
59
|
+
items = await readdir(full(path, true), { withFileTypes: true });
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (isMissing(error))
|
|
63
|
+
return [];
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
return items
|
|
67
|
+
.filter((item) => item.isFile() || item.isDirectory())
|
|
68
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
|
69
|
+
.map((item) => ({ name: item.name, type: item.isFile() ? "file" : "directory" }));
|
|
70
|
+
},
|
|
71
|
+
/**
|
|
72
|
+
* A content hash, not an mtime: a checkout that rewrites identical bytes
|
|
73
|
+
* must not cause a conflict.
|
|
74
|
+
*/
|
|
75
|
+
async revision(path) {
|
|
76
|
+
const bytes = await readBytes(path);
|
|
77
|
+
if (bytes === null)
|
|
78
|
+
return null;
|
|
79
|
+
return createHash("sha256").update(bytes).digest("hex").slice(0, 16);
|
|
80
|
+
},
|
|
81
|
+
async apply(input) {
|
|
82
|
+
checkChangePaths(input);
|
|
83
|
+
await assertExpected(this, input);
|
|
84
|
+
// In-memory undo of every overwrite and removal. Content trees are small,
|
|
85
|
+
// so no journal is necessary.
|
|
86
|
+
const undo = [];
|
|
87
|
+
const staging = [];
|
|
88
|
+
try {
|
|
89
|
+
for (const change of input.changes) {
|
|
90
|
+
if (change.type === "write") {
|
|
91
|
+
const target = full(change.path);
|
|
92
|
+
const previous = await readBytes(change.path);
|
|
93
|
+
undo.push(async () => {
|
|
94
|
+
if (previous === null)
|
|
95
|
+
await rm(target, { force: true });
|
|
96
|
+
else
|
|
97
|
+
await writeFile(target, previous);
|
|
98
|
+
});
|
|
99
|
+
await mkdir(dirname(target), { recursive: true });
|
|
100
|
+
// Write beside the target and rename, so a reader (the Astro dev
|
|
101
|
+
// server) never sees a partial file.
|
|
102
|
+
const staged = `${target}.mica-${process.pid}-${staging.length}`;
|
|
103
|
+
staging.push(staged);
|
|
104
|
+
await writeFile(staged, change.contents);
|
|
105
|
+
await rename(staged, target);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const target = full(change.path);
|
|
109
|
+
if (change.type === "delete") {
|
|
110
|
+
const previous = await readBytes(change.path);
|
|
111
|
+
if (previous === null)
|
|
112
|
+
continue;
|
|
113
|
+
undo.push(async () => {
|
|
114
|
+
await mkdir(dirname(target), { recursive: true });
|
|
115
|
+
await writeFile(target, previous);
|
|
116
|
+
});
|
|
117
|
+
await unlink(target);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
const saved = await snapshotTree(this, change.path);
|
|
121
|
+
undo.push(async () => {
|
|
122
|
+
for (const [path, bytes] of saved) {
|
|
123
|
+
const restored = full(path);
|
|
124
|
+
await mkdir(dirname(restored), { recursive: true });
|
|
125
|
+
await writeFile(restored, bytes);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
await rm(target, { recursive: true, force: true });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
// Reverse order, so a path written and then deleted comes back in its first state.
|
|
133
|
+
for (const step of undo.reverse()) {
|
|
134
|
+
// The original failure is what matters, not a rollback failure.
|
|
135
|
+
await step().catch(() => { });
|
|
136
|
+
}
|
|
137
|
+
for (const staged of staging)
|
|
138
|
+
await rm(staged, { force: true }).catch(() => { });
|
|
139
|
+
throw error instanceof FilesError
|
|
140
|
+
? error
|
|
141
|
+
: new FilesError(`Could not apply changes to ${base}: ${error.message}`);
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
async function assertExpected(files, input) {
|
|
147
|
+
if (!input.expect)
|
|
148
|
+
return;
|
|
149
|
+
const stale = [];
|
|
150
|
+
for (const [path, expected] of Object.entries(input.expect)) {
|
|
151
|
+
if ((await files.revision(path)) !== expected)
|
|
152
|
+
stale.push(path);
|
|
153
|
+
}
|
|
154
|
+
if (stale.length > 0) {
|
|
155
|
+
throw new ConflictError("This content changed after you opened it. Reload to see the current version.", stale);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/** Every file under `path`, so a tree deletion can be undone. */
|
|
159
|
+
async function snapshotTree(files, path) {
|
|
160
|
+
const saved = [];
|
|
161
|
+
const walk = async (at) => {
|
|
162
|
+
for (const item of await files.list(at)) {
|
|
163
|
+
const child = `${at}/${item.name}`;
|
|
164
|
+
if (item.type === "directory") {
|
|
165
|
+
await walk(child);
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const bytes = await files.readBinary(child);
|
|
169
|
+
if (bytes !== null)
|
|
170
|
+
saved.push([child, bytes]);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
await walk(path);
|
|
174
|
+
return saved;
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/workspace/files.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The content files of a working tree: the port everything reads and saves\n * through, and its implementation. It extends `ContentSource`, so the Astro\n * build and Mica share the same content reading code. `apply` is atomic: an\n * entry is several files, and half of one is corruption.\n */\n\nimport { createHash } from \"node:crypto\";\nimport { mkdir, readFile, readdir, rename, rm, unlink, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\n\nimport { contentPath, type ContentSource } from \"@micacms/core\";\nimport { isMissing, within } from \"@micacms/core/node\";\n\nexport class FilesError extends Error {\n override name = \"FilesError\";\n}\n\n/** A file changed under an editor. The editor can recover: reload and apply again. */\nexport class ConflictError extends FilesError {\n override name = \"ConflictError\";\n constructor(\n message: string,\n /** Paths whose revision no longer matched. */\n readonly paths: string[],\n ) {\n super(message);\n }\n}\n\n/** Who a commit names. */\nexport interface Author {\n name: string;\n email: string;\n}\n\nexport type FileChange =\n | { type: \"write\"; path: string; contents: string | Uint8Array }\n | { type: \"delete\"; path: string }\n /** Deletes every file under `path`. Removing an entry removes its directory. */\n | { type: \"deleteTree\"; path: string };\n\nexport interface FileChanges {\n changes: FileChange[];\n /**\n * Revisions the edit was based on, per path, so editors of different entries\n * never block each other. Null asserts that the path does not exist. Omitted,\n * the write is unconditional.\n */\n expect?: Record<string, string | null>;\n}\n\nexport interface ContentFiles extends ContentSource {\n /** Bytes of a file, for media. Null when there is no such file. */\n readBinary(path: string): Promise<Uint8Array | null>;\n\n /**\n * An opaque token for the current state of `path`, or null when it is absent.\n * Compare only for equality.\n */\n revision(path: string): Promise<string | null>;\n\n /**\n * Applies every change, or none of them. Throws `ConflictError` when any\n * `expect` no longer holds.\n */\n apply(input: FileChanges): Promise<void>;\n}\n\n/**\n * Refuses, before any write, a change or expectation that names the content\n * root or a path outside it.\n */\nexport function checkChangePaths(input: FileChanges): void {\n for (const change of input.changes) contentPath(change.path);\n for (const path of Object.keys(input.expect ?? {})) contentPath(path);\n}\n\nexport interface ContentFilesOptions {\n root: string;\n}\n\nexport function contentFiles(options: ContentFilesOptions): ContentFiles {\n const base = resolve(options.root);\n const full = (path: string, allowRoot = false) => within(base, path, { allowRoot });\n\n const readBytes = async (path: string): Promise<Uint8Array | null> => {\n try {\n return await readFile(full(path));\n } catch (error) {\n if (isMissing(error)) return null;\n throw error;\n }\n };\n\n return {\n origin: base,\n\n async read(path) {\n const bytes = await readBytes(path);\n return bytes === null ? null : Buffer.from(bytes).toString(\"utf8\");\n },\n\n readBinary: readBytes,\n\n async list(path) {\n let items;\n try {\n items = await readdir(full(path, true), { withFileTypes: true });\n } catch (error) {\n if (isMissing(error)) return [];\n throw error;\n }\n\n return items\n .filter((item) => item.isFile() || item.isDirectory())\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((item) => ({ name: item.name, type: item.isFile() ? (\"file\" as const) : (\"directory\" as const) }));\n },\n\n /**\n * A content hash, not an mtime: a checkout that rewrites identical bytes\n * must not cause a conflict.\n */\n async revision(path) {\n const bytes = await readBytes(path);\n if (bytes === null) return null;\n return createHash(\"sha256\").update(bytes).digest(\"hex\").slice(0, 16);\n },\n\n async apply(input: FileChanges): Promise<void> {\n checkChangePaths(input);\n await assertExpected(this, input);\n\n // In-memory undo of every overwrite and removal. Content trees are small,\n // so no journal is necessary.\n const undo: Array<() => Promise<void>> = [];\n const staging: string[] = [];\n\n try {\n for (const change of input.changes) {\n if (change.type === \"write\") {\n const target = full(change.path);\n const previous = await readBytes(change.path);\n\n undo.push(async () => {\n if (previous === null) await rm(target, { force: true });\n else await writeFile(target, previous);\n });\n\n await mkdir(dirname(target), { recursive: true });\n // Write beside the target and rename, so a reader (the Astro dev\n // server) never sees a partial file.\n const staged = `${target}.mica-${process.pid}-${staging.length}`;\n staging.push(staged);\n await writeFile(staged, change.contents);\n await rename(staged, target);\n continue;\n }\n\n const target = full(change.path);\n\n if (change.type === \"delete\") {\n const previous = await readBytes(change.path);\n if (previous === null) continue;\n\n undo.push(async () => {\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, previous);\n });\n await unlink(target);\n continue;\n }\n\n const saved = await snapshotTree(this, change.path);\n undo.push(async () => {\n for (const [path, bytes] of saved) {\n const restored = full(path);\n await mkdir(dirname(restored), { recursive: true });\n await writeFile(restored, bytes);\n }\n });\n await rm(target, { recursive: true, force: true });\n }\n } catch (error) {\n // Reverse order, so a path written and then deleted comes back in its first state.\n for (const step of undo.reverse()) {\n // The original failure is what matters, not a rollback failure.\n await step().catch(() => {});\n }\n for (const staged of staging) await rm(staged, { force: true }).catch(() => {});\n\n throw error instanceof FilesError\n ? error\n : new FilesError(\n `Could not apply changes to ${base}: ${(error as Error).message}`,\n );\n }\n },\n };\n}\n\nasync function assertExpected(\n files: ContentFiles,\n input: FileChanges,\n): Promise<void> {\n if (!input.expect) return;\n\n const stale: string[] = [];\n for (const [path, expected] of Object.entries(input.expect)) {\n if ((await files.revision(path)) !== expected) stale.push(path);\n }\n\n if (stale.length > 0) {\n throw new ConflictError(\n \"This content changed after you opened it. Reload to see the current version.\",\n stale,\n );\n }\n}\n\n/** Every file under `path`, so a tree deletion can be undone. */\nasync function snapshotTree(\n files: ContentFiles,\n path: string,\n): Promise<Array<[string, Uint8Array]>> {\n const saved: Array<[string, Uint8Array]> = [];\n\n const walk = async (at: string): Promise<void> => {\n for (const item of await files.list(at)) {\n const child = `${at}/${item.name}`;\n if (item.type === \"directory\") {\n await walk(child);\n continue;\n }\n const bytes = await files.readBinary(child);\n if (bytes !== null) saved.push([child, bytes]);\n }\n };\n\n await walk(path);\n return saved;\n}\n"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spawns the `git` binary, so the developer's SSH agent, credential helper and
|
|
3
|
+
* remote configuration apply. A server-owned clone passes its own environment
|
|
4
|
+
* instead (`GitRunnerOptions.env`).
|
|
5
|
+
*/
|
|
6
|
+
export declare class GitError extends Error {
|
|
7
|
+
readonly stderr: string;
|
|
8
|
+
readonly exitCode: number | null;
|
|
9
|
+
/** What Git printed before it failed. A rejected push puts its porcelain lines here. */
|
|
10
|
+
readonly stdout: string;
|
|
11
|
+
name: string;
|
|
12
|
+
constructor(message: string, stderr: string, exitCode: number | null,
|
|
13
|
+
/** What Git printed before it failed. A rejected push puts its porcelain lines here. */
|
|
14
|
+
stdout?: string);
|
|
15
|
+
}
|
|
16
|
+
export interface GitCallOptions {
|
|
17
|
+
/** Written to Git's stdin, for `--pathspec-from-file=-` and similar. */
|
|
18
|
+
input?: string;
|
|
19
|
+
/** Added to the runner's environment for this call only. */
|
|
20
|
+
env?: NodeJS.ProcessEnv;
|
|
21
|
+
}
|
|
22
|
+
export interface GitRunner {
|
|
23
|
+
/** Runs `git` in the runner's directory. Trimmed stdout, or a `GitError`. */
|
|
24
|
+
run(args: string[], call?: GitCallOptions): Promise<string>;
|
|
25
|
+
/** Like `run`, but null instead of a throw — for questions Git may say no to. */
|
|
26
|
+
tryRun(args: string[], call?: GitCallOptions): Promise<string | null>;
|
|
27
|
+
}
|
|
28
|
+
export interface GitRunnerOptions {
|
|
29
|
+
/**
|
|
30
|
+
* The whole environment of every `git` call. Defaults to the developer's
|
|
31
|
+
* (`developerEnvironment`).
|
|
32
|
+
*/
|
|
33
|
+
env?: NodeJS.ProcessEnv;
|
|
34
|
+
timeoutMs?: number;
|
|
35
|
+
maxBuffer?: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The developer's own environment. `GIT_TERMINAL_PROMPT=0`: a credential prompt
|
|
39
|
+
* must fail, not hang the request.
|
|
40
|
+
*/
|
|
41
|
+
export declare function developerEnvironment(): NodeJS.ProcessEnv;
|
|
42
|
+
export declare function gitRunner(cwd: string, options?: GitRunnerOptions): GitRunner;
|
|
43
|
+
/** The first non-empty line, where Git puts its verdict. */
|
|
44
|
+
export declare function firstLine(text: string): string;
|
|
45
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/workspace/git.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,qBAAa,QAAS,SAAQ,KAAK;IAI/B,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAChC,wFAAwF;IACxF,QAAQ,CAAC,MAAM;IANR,IAAI,SAAc;gBAEzB,OAAO,EAAE,MAAM,EACN,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GAAG,IAAI;IAChC,wFAAwF;IAC/E,MAAM,SAAK;CAIvB;AAED,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,6EAA6E;IAC7E,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5D,iFAAiF;IACjF,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAAC,UAAU,CAExD;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS,CA4ChF;AAED,4DAA4D;AAC5D,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO9C"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spawns the `git` binary, so the developer's SSH agent, credential helper and
|
|
3
|
+
* remote configuration apply. A server-owned clone passes its own environment
|
|
4
|
+
* instead (`GitRunnerOptions.env`).
|
|
5
|
+
*/
|
|
6
|
+
import { execFile } from "node:child_process";
|
|
7
|
+
export class GitError extends Error {
|
|
8
|
+
stderr;
|
|
9
|
+
exitCode;
|
|
10
|
+
stdout;
|
|
11
|
+
name = "GitError";
|
|
12
|
+
constructor(message, stderr, exitCode,
|
|
13
|
+
/** What Git printed before it failed. A rejected push puts its porcelain lines here. */
|
|
14
|
+
stdout = "") {
|
|
15
|
+
super(message);
|
|
16
|
+
this.stderr = stderr;
|
|
17
|
+
this.exitCode = exitCode;
|
|
18
|
+
this.stdout = stdout;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The developer's own environment. `GIT_TERMINAL_PROMPT=0`: a credential prompt
|
|
23
|
+
* must fail, not hang the request.
|
|
24
|
+
*/
|
|
25
|
+
export function developerEnvironment() {
|
|
26
|
+
return { ...process.env, GIT_TERMINAL_PROMPT: "0" };
|
|
27
|
+
}
|
|
28
|
+
export function gitRunner(cwd, options = {}) {
|
|
29
|
+
const env = options.env ?? developerEnvironment();
|
|
30
|
+
const run = (args, call = {}) => new Promise((resolve, reject) => {
|
|
31
|
+
const child = execFile("git", args, {
|
|
32
|
+
cwd,
|
|
33
|
+
env: call.env ? { ...env, ...call.env } : env,
|
|
34
|
+
timeout: options.timeoutMs ?? 60_000,
|
|
35
|
+
maxBuffer: options.maxBuffer ?? 10 * 1024 * 1024,
|
|
36
|
+
}, (error, stdout, stderr) => {
|
|
37
|
+
if (error) {
|
|
38
|
+
const missing = error.code === "ENOENT";
|
|
39
|
+
reject(new GitError(missing
|
|
40
|
+
? "Git is not installed, or not on the PATH."
|
|
41
|
+
: firstLine(stderr) || error.message, stderr, missing ? null : (error.code ?? null), stdout));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
resolve(stdout.replace(/\n$/, ""));
|
|
45
|
+
});
|
|
46
|
+
if (call.input !== undefined)
|
|
47
|
+
child.stdin?.end(call.input);
|
|
48
|
+
});
|
|
49
|
+
return {
|
|
50
|
+
run,
|
|
51
|
+
async tryRun(args, call) {
|
|
52
|
+
try {
|
|
53
|
+
return await run(args, call);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/** The first non-empty line, where Git puts its verdict. */
|
|
62
|
+
export function firstLine(text) {
|
|
63
|
+
return (text
|
|
64
|
+
.split("\n")
|
|
65
|
+
.map((line) => line.trim())
|
|
66
|
+
.find((line) => line !== "") ?? "");
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/workspace/git.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,MAAM,OAAO,QAAS,SAAQ,KAAK;IAItB;IACA;IAEA;IANF,IAAI,GAAG,UAAU,CAAC;IAC3B,YACE,OAAe,EACN,MAAc,EACd,QAAuB;IAChC,wFAAwF;IAC/E,SAAS,EAAE;QAEpB,KAAK,CAAC,OAAO,CAAC,CAAC;QALN,WAAM,GAAN,MAAM,CAAQ;QACd,aAAQ,GAAR,QAAQ,CAAe;QAEvB,WAAM,GAAN,MAAM,CAAK;IAGtB,CAAC;CACF;AA0BD;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,mBAAmB,EAAE,GAAG,EAAE,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAAW,EAAE,UAA4B,EAAE;IACnE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAClD,MAAM,GAAG,GAAG,CAAC,IAAc,EAAE,OAAuB,EAAE,EAAmB,EAAE,CACzE,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC9B,MAAM,KAAK,GAAG,QAAQ,CACpB,KAAK,EACL,IAAI,EACJ;YACE,GAAG;YACH,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG;YAC7C,OAAO,EAAE,OAAO,CAAC,SAAS,IAAI,MAAM;YACpC,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE,GAAG,IAAI,GAAG,IAAI;SACjD,EACD,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACxB,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,OAAO,GAAI,KAA+B,CAAC,IAAI,KAAK,QAAQ,CAAC;gBACnE,MAAM,CACJ,IAAI,QAAQ,CACV,OAAO;oBACL,CAAC,CAAC,2CAA2C;oBAC7C,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,EACtC,MAAM,EACN,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,KAA2B,CAAC,IAAI,IAAI,IAAI,CAAC,EAC5D,MAAM,CACP,CACF,CAAC;gBACF,OAAO;YACT,CAAC;YACD,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;QACrC,CAAC,CACF,CAAC;QACF,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;YAAE,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEL,OAAO;QACL,GAAG;QACH,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI;YACrB,IAAI,CAAC;gBACH,OAAO,MAAM,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,CACL,IAAI;SACD,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI,EAAE,CACrC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Spawns the `git` binary, so the developer's SSH agent, credential helper and\n * remote configuration apply. A server-owned clone passes its own environment\n * instead (`GitRunnerOptions.env`).\n */\n\nimport { execFile } from \"node:child_process\";\n\nexport class GitError extends Error {\n override name = \"GitError\";\n constructor(\n message: string,\n readonly stderr: string,\n readonly exitCode: number | null,\n /** What Git printed before it failed. A rejected push puts its porcelain lines here. */\n readonly stdout = \"\",\n ) {\n super(message);\n }\n}\n\nexport interface GitCallOptions {\n /** Written to Git's stdin, for `--pathspec-from-file=-` and similar. */\n input?: string;\n /** Added to the runner's environment for this call only. */\n env?: NodeJS.ProcessEnv;\n}\n\nexport interface GitRunner {\n /** Runs `git` in the runner's directory. Trimmed stdout, or a `GitError`. */\n run(args: string[], call?: GitCallOptions): Promise<string>;\n /** Like `run`, but null instead of a throw — for questions Git may say no to. */\n tryRun(args: string[], call?: GitCallOptions): Promise<string | null>;\n}\n\nexport interface GitRunnerOptions {\n /**\n * The whole environment of every `git` call. Defaults to the developer's\n * (`developerEnvironment`).\n */\n env?: NodeJS.ProcessEnv;\n timeoutMs?: number;\n maxBuffer?: number;\n}\n\n/**\n * The developer's own environment. `GIT_TERMINAL_PROMPT=0`: a credential prompt\n * must fail, not hang the request.\n */\nexport function developerEnvironment(): NodeJS.ProcessEnv {\n return { ...process.env, GIT_TERMINAL_PROMPT: \"0\" };\n}\n\nexport function gitRunner(cwd: string, options: GitRunnerOptions = {}): GitRunner {\n const env = options.env ?? developerEnvironment();\n const run = (args: string[], call: GitCallOptions = {}): Promise<string> =>\n new Promise((resolve, reject) => {\n const child = execFile(\n \"git\",\n args,\n {\n cwd,\n env: call.env ? { ...env, ...call.env } : env,\n timeout: options.timeoutMs ?? 60_000,\n maxBuffer: options.maxBuffer ?? 10 * 1024 * 1024,\n },\n (error, stdout, stderr) => {\n if (error) {\n const missing = (error as NodeJS.ErrnoException).code === \"ENOENT\";\n reject(\n new GitError(\n missing\n ? \"Git is not installed, or not on the PATH.\"\n : firstLine(stderr) || error.message,\n stderr,\n missing ? null : ((error as { code?: number }).code ?? null),\n stdout,\n ),\n );\n return;\n }\n resolve(stdout.replace(/\\n$/, \"\"));\n },\n );\n if (call.input !== undefined) child.stdin?.end(call.input);\n });\n\n return {\n run,\n async tryRun(args, call) {\n try {\n return await run(args, call);\n } catch {\n return null;\n }\n },\n };\n}\n\n/** The first non-empty line, where Git puts its verdict. */\nexport function firstLine(text: string): string {\n return (\n text\n .split(\"\\n\")\n .map((line) => line.trim())\n .find((line) => line !== \"\") ?? \"\"\n );\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two locks of a shared working tree: `remote` (fetch and push, one at a
|
|
3
|
+
* time) and `tree` (read/write; saves, discards, commits and fast-forwards
|
|
4
|
+
* write). A save during a commit could otherwise put half an entry into the
|
|
5
|
+
* commit, and a read during a fast-forward could see a half-written file.
|
|
6
|
+
*
|
|
7
|
+
* Both wait, they do not refuse. Take `remote` first, then `tree`, so two
|
|
8
|
+
* operations never wait on each other. No network call may run while `tree` is
|
|
9
|
+
* held: a slow push must not block autosave.
|
|
10
|
+
*/
|
|
11
|
+
import type { ContentFiles } from "./files.js";
|
|
12
|
+
/** Runs one function at a time, in arrival order. */
|
|
13
|
+
export interface Mutex {
|
|
14
|
+
run<T>(fn: () => Promise<T>): Promise<T>;
|
|
15
|
+
}
|
|
16
|
+
/** Many readers or one writer, in arrival order. A waiting writer holds back later readers. */
|
|
17
|
+
export interface ReadWriteLock {
|
|
18
|
+
read<T>(fn: () => Promise<T>): Promise<T>;
|
|
19
|
+
write<T>(fn: () => Promise<T>): Promise<T>;
|
|
20
|
+
}
|
|
21
|
+
export interface WorkspaceLocks {
|
|
22
|
+
remote: Mutex;
|
|
23
|
+
tree: ReadWriteLock;
|
|
24
|
+
}
|
|
25
|
+
export declare function createWorkspaceLocks(): WorkspaceLocks;
|
|
26
|
+
export declare function createMutex(): Mutex;
|
|
27
|
+
export declare function createReadWriteLock(): ReadWriteLock;
|
|
28
|
+
/**
|
|
29
|
+
* Files behind the tree lock. The staging service does not use it: it holds the
|
|
30
|
+
* lock around whole operations.
|
|
31
|
+
*/
|
|
32
|
+
export declare function lockedFiles(files: ContentFiles, tree: ReadWriteLock): ContentFiles;
|
|
33
|
+
//# sourceMappingURL=locks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locks.d.ts","sourceRoot":"","sources":["../../src/workspace/locks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,qDAAqD;AACrD,MAAM,WAAW,KAAK;IACpB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC1C;AAED,+FAA+F;AAC/F,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1C,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,KAAK,CAAC;IACd,IAAI,EAAE,aAAa,CAAC;CACrB;AAED,wBAAgB,oBAAoB,IAAI,cAAc,CAErD;AAED,wBAAgB,WAAW,IAAI,KAAK,CAGnC;AAED,wBAAgB,mBAAmB,IAAI,aAAa,CA8CnD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,aAAa,GAClB,YAAY,CASd"}
|