@decohere/core 0.0.1-dev.116

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.
Files changed (262) hide show
  1. package/commonjs/src/caching/cache-manager.js +98 -0
  2. package/commonjs/src/caching/cache.decorator.js +69 -0
  3. package/commonjs/src/caching/cache.js +6 -0
  4. package/commonjs/src/caching/index.js +23 -0
  5. package/commonjs/src/caching/invalidate-cache.decorator.js +92 -0
  6. package/commonjs/src/caching/memoize.decorator.js +36 -0
  7. package/commonjs/src/caching/node-cache-memoize.adapter.js +49 -0
  8. package/commonjs/src/cli/action.js +65 -0
  9. package/commonjs/src/cli/command.js +127 -0
  10. package/commonjs/src/cli/index.js +61 -0
  11. package/commonjs/src/cli/module.type.js +18 -0
  12. package/commonjs/src/cli/options.js +115 -0
  13. package/commonjs/src/collections/collections.js +21 -0
  14. package/commonjs/src/collections/find-duplicates.js +35 -0
  15. package/commonjs/src/collections/index.js +52 -0
  16. package/commonjs/src/collections/merge-arrays.js +34 -0
  17. package/commonjs/src/collections/sum.js +63 -0
  18. package/commonjs/src/collections/unique-objects.js +39 -0
  19. package/commonjs/src/composition/index.js +4 -0
  20. package/commonjs/src/configuration/configuration.types.js +11 -0
  21. package/commonjs/src/configuration/index.js +18 -0
  22. package/commonjs/src/diagnostics/index.js +22 -0
  23. package/commonjs/src/diagnostics/trace.js +86 -0
  24. package/commonjs/src/extensibility/decorator-factory-base.js +22 -0
  25. package/commonjs/src/extensibility/decorator-factory.js +31 -0
  26. package/commonjs/src/extensibility/extension.js +37 -0
  27. package/commonjs/src/extensibility/index.js +23 -0
  28. package/commonjs/src/extensibility/mixwith.js +36 -0
  29. package/commonjs/src/extensibility/pipeline.js +56 -0
  30. package/commonjs/src/extensibility/step.js +18 -0
  31. package/commonjs/src/interop/docker/docker.js +54 -0
  32. package/commonjs/src/interop/errors/interop.error.js +12 -0
  33. package/commonjs/src/interop/git/git.js +134 -0
  34. package/commonjs/src/interop/git/git.types.js +4 -0
  35. package/commonjs/src/interop/index.js +97 -0
  36. package/commonjs/src/interop/node/index.js +18 -0
  37. package/commonjs/src/interop/node/node.js +45 -0
  38. package/commonjs/src/interop/npm/npm.js +231 -0
  39. package/commonjs/src/interop/npm/npm.types.js +16 -0
  40. package/commonjs/src/interop/pnpm/pnpm.js +34 -0
  41. package/commonjs/src/interop/pnpm/pnpm.types.js +4 -0
  42. package/commonjs/src/interop/shell/shell.argv.js +45 -0
  43. package/commonjs/src/interop/shell/shell.js +105 -0
  44. package/commonjs/src/interop/shell/shell.types.js +4 -0
  45. package/commonjs/src/interop/types/detect-package-manager.js +71 -0
  46. package/commonjs/src/interop/types/package-manager.js +4 -0
  47. package/commonjs/src/interop/yarn/yarn.js +34 -0
  48. package/commonjs/src/interop/yarn/yarn.types.js +4 -0
  49. package/commonjs/src/io/copy-file.js +25 -0
  50. package/commonjs/src/io/delete-file.js +21 -0
  51. package/commonjs/src/io/directory-exists.js +24 -0
  52. package/commonjs/src/io/file-exists.js +19 -0
  53. package/commonjs/src/io/find-directories.js +21 -0
  54. package/commonjs/src/io/find-file.js +45 -0
  55. package/commonjs/src/io/index.js +66 -0
  56. package/commonjs/src/io/io.js +28 -0
  57. package/commonjs/src/io/read-file.js +39 -0
  58. package/commonjs/src/io/remove-dir.js +22 -0
  59. package/commonjs/src/io/types/directory.type.js +4 -0
  60. package/commonjs/src/io/types/file.js +28 -0
  61. package/commonjs/src/io/types/index.js +19 -0
  62. package/commonjs/src/io/url-to-path.js +33 -0
  63. package/commonjs/src/io/watch.js +261 -0
  64. package/commonjs/src/io/write-file.js +30 -0
  65. package/commonjs/src/objects/deep-merge.js +67 -0
  66. package/commonjs/src/objects/index.js +11 -0
  67. package/commonjs/src/reflection/index.js +20 -0
  68. package/commonjs/src/reflection/types/index.js +18 -0
  69. package/commonjs/src/reflection/types/reflection.types.js +26 -0
  70. package/commonjs/src/reflection/utilities.js +118 -0
  71. package/commonjs/src/semver/index.js +18 -0
  72. package/commonjs/src/semver/semver.js +92 -0
  73. package/commonjs/src/system/camel-case.js +13 -0
  74. package/commonjs/src/system/debounce.js +19 -0
  75. package/commonjs/src/system/decorator.js +46 -0
  76. package/commonjs/src/system/environment.js +23 -0
  77. package/commonjs/src/system/function.types.js +18 -0
  78. package/commonjs/src/system/index.js +24 -0
  79. package/commonjs/src/system/retry.decorator.js +40 -0
  80. package/commonjs/src/system/sleep.js +13 -0
  81. package/commonjs/src/system/type.utils.js +4 -0
  82. package/commonjs/src/testing/flush-promises.js +16 -0
  83. package/commonjs/src/testing/glob-with-memfs.js +22 -0
  84. package/commonjs/src/testing/index.js +22 -0
  85. package/commonjs/src/testing/memfs.js +52 -0
  86. package/commonjs/src/testing/mock-logger.js +36 -0
  87. package/commonjs/src/testing/spy-on-constructor.js +27 -0
  88. package/es6/src/caching/cache-manager.js +82 -0
  89. package/es6/src/caching/cache.decorator.js +51 -0
  90. package/es6/src/caching/cache.js +3 -0
  91. package/es6/src/caching/index.js +6 -0
  92. package/es6/src/caching/invalidate-cache.decorator.js +71 -0
  93. package/es6/src/caching/memoize.decorator.js +27 -0
  94. package/es6/src/caching/node-cache-memoize.adapter.js +37 -0
  95. package/es6/src/cli/action.js +47 -0
  96. package/es6/src/cli/command.js +106 -0
  97. package/es6/src/cli/index.js +4 -0
  98. package/es6/src/cli/module.type.js +11 -0
  99. package/es6/src/cli/options.js +76 -0
  100. package/es6/src/collections/collections.js +4 -0
  101. package/es6/src/collections/find-duplicates.js +17 -0
  102. package/es6/src/collections/index.js +1 -0
  103. package/es6/src/collections/merge-arrays.js +16 -0
  104. package/es6/src/collections/sum.js +45 -0
  105. package/es6/src/collections/unique-objects.js +21 -0
  106. package/es6/src/composition/index.js +1 -0
  107. package/es6/src/configuration/configuration.types.js +1 -0
  108. package/es6/src/configuration/index.js +1 -0
  109. package/es6/src/diagnostics/index.js +1 -0
  110. package/es6/src/diagnostics/trace.js +68 -0
  111. package/es6/src/extensibility/decorator-factory-base.js +39 -0
  112. package/es6/src/extensibility/decorator-factory.js +21 -0
  113. package/es6/src/extensibility/extension.js +27 -0
  114. package/es6/src/extensibility/index.js +6 -0
  115. package/es6/src/extensibility/mixwith.js +26 -0
  116. package/es6/src/extensibility/pipeline.js +46 -0
  117. package/es6/src/extensibility/step.js +16 -0
  118. package/es6/src/interop/docker/docker.js +44 -0
  119. package/es6/src/interop/errors/interop.error.js +2 -0
  120. package/es6/src/interop/git/git.js +124 -0
  121. package/es6/src/interop/git/git.types.js +1 -0
  122. package/es6/src/interop/index.js +21 -0
  123. package/es6/src/interop/node/index.js +1 -0
  124. package/es6/src/interop/node/node.js +35 -0
  125. package/es6/src/interop/npm/npm.js +180 -0
  126. package/es6/src/interop/npm/npm.types.js +6 -0
  127. package/es6/src/interop/pnpm/pnpm.js +24 -0
  128. package/es6/src/interop/pnpm/pnpm.types.js +1 -0
  129. package/es6/src/interop/shell/shell.argv.js +35 -0
  130. package/es6/src/interop/shell/shell.js +95 -0
  131. package/es6/src/interop/shell/shell.types.js +1 -0
  132. package/es6/src/interop/types/detect-package-manager.js +50 -0
  133. package/es6/src/interop/types/package-manager.js +1 -0
  134. package/es6/src/interop/yarn/yarn.js +24 -0
  135. package/es6/src/interop/yarn/yarn.types.js +1 -0
  136. package/es6/src/io/copy-file.js +10 -0
  137. package/es6/src/io/delete-file.js +6 -0
  138. package/es6/src/io/directory-exists.js +9 -0
  139. package/es6/src/io/file-exists.js +9 -0
  140. package/es6/src/io/find-directories.js +11 -0
  141. package/es6/src/io/find-file.js +27 -0
  142. package/es6/src/io/index.js +2 -0
  143. package/es6/src/io/io.js +11 -0
  144. package/es6/src/io/read-file.js +13 -0
  145. package/es6/src/io/remove-dir.js +7 -0
  146. package/es6/src/io/types/directory.type.js +1 -0
  147. package/es6/src/io/types/file.js +18 -0
  148. package/es6/src/io/types/index.js +2 -0
  149. package/es6/src/io/url-to-path.js +15 -0
  150. package/es6/src/io/watch.js +238 -0
  151. package/es6/src/io/write-file.js +15 -0
  152. package/es6/src/objects/deep-merge.js +57 -0
  153. package/es6/src/objects/index.js +1 -0
  154. package/es6/src/reflection/index.js +3 -0
  155. package/es6/src/reflection/types/index.js +1 -0
  156. package/es6/src/reflection/types/reflection.types.js +8 -0
  157. package/es6/src/reflection/utilities.js +74 -0
  158. package/es6/src/semver/index.js +1 -0
  159. package/es6/src/semver/semver.js +71 -0
  160. package/es6/src/system/camel-case.js +3 -0
  161. package/es6/src/system/debounce.js +9 -0
  162. package/es6/src/system/decorator.js +30 -0
  163. package/es6/src/system/environment.js +5 -0
  164. package/es6/src/system/function.types.js +26 -0
  165. package/es6/src/system/index.js +7 -0
  166. package/es6/src/system/retry.decorator.js +30 -0
  167. package/es6/src/system/sleep.js +3 -0
  168. package/es6/src/system/type.utils.js +1 -0
  169. package/es6/src/testing/flush-promises.js +6 -0
  170. package/es6/src/testing/glob-with-memfs.js +20 -0
  171. package/es6/src/testing/index.js +5 -0
  172. package/es6/src/testing/memfs.js +25 -0
  173. package/es6/src/testing/mock-logger.js +26 -0
  174. package/es6/src/testing/spy-on-constructor.js +31 -0
  175. package/package.json +106 -0
  176. package/types/src/caching/cache-manager.d.ts +59 -0
  177. package/types/src/caching/cache.d.ts +11 -0
  178. package/types/src/caching/cache.decorator.d.ts +18 -0
  179. package/types/src/caching/index.d.ts +6 -0
  180. package/types/src/caching/invalidate-cache.decorator.d.ts +17 -0
  181. package/types/src/caching/memoize.decorator.d.ts +16 -0
  182. package/types/src/caching/node-cache-memoize.adapter.d.ts +22 -0
  183. package/types/src/cli/action.d.ts +36 -0
  184. package/types/src/cli/command.d.ts +34 -0
  185. package/types/src/cli/index.d.ts +7 -0
  186. package/types/src/cli/module.type.d.ts +36 -0
  187. package/types/src/cli/options.d.ts +28 -0
  188. package/types/src/collections/collections.d.ts +4 -0
  189. package/types/src/collections/find-duplicates.d.ts +2 -0
  190. package/types/src/collections/index.d.ts +1 -0
  191. package/types/src/collections/merge-arrays.d.ts +2 -0
  192. package/types/src/collections/sum.d.ts +4 -0
  193. package/types/src/collections/unique-objects.d.ts +2 -0
  194. package/types/src/composition/index.d.ts +37 -0
  195. package/types/src/configuration/configuration.types.d.ts +10 -0
  196. package/types/src/configuration/index.d.ts +1 -0
  197. package/types/src/diagnostics/index.d.ts +1 -0
  198. package/types/src/diagnostics/trace.d.ts +10 -0
  199. package/types/src/extensibility/decorator-factory-base.d.ts +39 -0
  200. package/types/src/extensibility/decorator-factory.d.ts +19 -0
  201. package/types/src/extensibility/extension.d.ts +9 -0
  202. package/types/src/extensibility/index.d.ts +6 -0
  203. package/types/src/extensibility/mixwith.d.ts +6 -0
  204. package/types/src/extensibility/pipeline.d.ts +12 -0
  205. package/types/src/extensibility/step.d.ts +16 -0
  206. package/types/src/interop/docker/docker.d.ts +19 -0
  207. package/types/src/interop/errors/interop.error.d.ts +2 -0
  208. package/types/src/interop/git/git.d.ts +16 -0
  209. package/types/src/interop/git/git.types.d.ts +14 -0
  210. package/types/src/interop/index.d.ts +14 -0
  211. package/types/src/interop/node/index.d.ts +1 -0
  212. package/types/src/interop/node/node.d.ts +5 -0
  213. package/types/src/interop/npm/npm.d.ts +29 -0
  214. package/types/src/interop/npm/npm.types.d.ts +24 -0
  215. package/types/src/interop/pnpm/pnpm.d.ts +9 -0
  216. package/types/src/interop/pnpm/pnpm.types.d.ts +3 -0
  217. package/types/src/interop/shell/shell.argv.d.ts +5 -0
  218. package/types/src/interop/shell/shell.d.ts +6 -0
  219. package/types/src/interop/shell/shell.types.d.ts +9 -0
  220. package/types/src/interop/types/detect-package-manager.d.ts +4 -0
  221. package/types/src/interop/types/package-manager.d.ts +10 -0
  222. package/types/src/interop/yarn/yarn.d.ts +9 -0
  223. package/types/src/interop/yarn/yarn.types.d.ts +3 -0
  224. package/types/src/io/copy-file.d.ts +4 -0
  225. package/types/src/io/delete-file.d.ts +1 -0
  226. package/types/src/io/directory-exists.d.ts +1 -0
  227. package/types/src/io/file-exists.d.ts +1 -0
  228. package/types/src/io/find-directories.d.ts +2 -0
  229. package/types/src/io/find-file.d.ts +9 -0
  230. package/types/src/io/index.d.ts +2 -0
  231. package/types/src/io/io.d.ts +11 -0
  232. package/types/src/io/read-file.d.ts +4 -0
  233. package/types/src/io/remove-dir.d.ts +5 -0
  234. package/types/src/io/types/directory.type.d.ts +4 -0
  235. package/types/src/io/types/file.d.ts +20 -0
  236. package/types/src/io/types/index.d.ts +2 -0
  237. package/types/src/io/url-to-path.d.ts +2 -0
  238. package/types/src/io/watch.d.ts +16 -0
  239. package/types/src/io/write-file.d.ts +5 -0
  240. package/types/src/objects/deep-merge.d.ts +41 -0
  241. package/types/src/objects/index.d.ts +1 -0
  242. package/types/src/reflection/index.d.ts +3 -0
  243. package/types/src/reflection/types/index.d.ts +1 -0
  244. package/types/src/reflection/types/reflection.types.d.ts +21 -0
  245. package/types/src/reflection/utilities.d.ts +27 -0
  246. package/types/src/semver/index.d.ts +1 -0
  247. package/types/src/semver/semver.d.ts +18 -0
  248. package/types/src/system/camel-case.d.ts +1 -0
  249. package/types/src/system/debounce.d.ts +1 -0
  250. package/types/src/system/decorator.d.ts +15 -0
  251. package/types/src/system/environment.d.ts +6 -0
  252. package/types/src/system/function.types.d.ts +55 -0
  253. package/types/src/system/index.d.ts +7 -0
  254. package/types/src/system/retry.decorator.d.ts +6 -0
  255. package/types/src/system/sleep.d.ts +1 -0
  256. package/types/src/system/type.utils.d.ts +1 -0
  257. package/types/src/testing/flush-promises.d.ts +1 -0
  258. package/types/src/testing/glob-with-memfs.d.ts +3 -0
  259. package/types/src/testing/index.d.ts +5 -0
  260. package/types/src/testing/memfs.d.ts +5 -0
  261. package/types/src/testing/mock-logger.d.ts +13 -0
  262. package/types/src/testing/spy-on-constructor.d.ts +21 -0
@@ -0,0 +1,26 @@
1
+ const BLOCKED_PROTOTYPE_KEYS = new Set([
2
+ "constructor",
3
+ "prototype",
4
+ "name",
5
+ "length"
6
+ ]);
7
+ function copyPrototypeProperties(target, source) {
8
+ for (const key of Reflect.ownKeys(source)){
9
+ if (typeof key === "string" && BLOCKED_PROTOTYPE_KEYS.has(key)) {
10
+ continue;
11
+ }
12
+ const descriptor = Object.getOwnPropertyDescriptor(source, key);
13
+ if (descriptor == null) {
14
+ continue;
15
+ }
16
+ Object.defineProperty(target, key, descriptor);
17
+ }
18
+ }
19
+ export function mixwith(...mixins) {
20
+ class Mixed {
21
+ }
22
+ for (const mixin of mixins){
23
+ copyPrototypeProperties(Mixed.prototype, mixin.prototype);
24
+ }
25
+ return Mixed;
26
+ }
@@ -0,0 +1,46 @@
1
+ import { scribe } from "@decohere/scribe";
2
+ export class Pipeline {
3
+ stack;
4
+ logger = scribe.logger(Pipeline.name);
5
+ currentStep;
6
+ constructor(...steps){
7
+ this.stack = steps;
8
+ }
9
+ [Symbol.dispose]() {
10
+ for (const [, step] of this.stack){
11
+ if (Symbol.dispose in step) {
12
+ step[Symbol.dispose]();
13
+ }
14
+ }
15
+ }
16
+ async start(context) {
17
+ const runStep = async (index)=>{
18
+ const [key, middleware, when] = this.stack[index] ?? [];
19
+ if (middleware == null) {
20
+ return;
21
+ }
22
+ if (when != null && !when(context)) {
23
+ this.logger.info(`Skipping step ${key}`);
24
+ return await runStep(index + 1);
25
+ }
26
+ this.currentStep = key;
27
+ this.logger.info(`Running step ${key}`);
28
+ await middleware.run(context, async ()=>{
29
+ await runStep(index + 1);
30
+ });
31
+ };
32
+ try {
33
+ await runStep(0);
34
+ } catch (error) {
35
+ const step = this.currentStep ?? "unknown";
36
+ if (error instanceof Error) {
37
+ throw new Error(`Pipeline step '${step}' failed: ${error.message}`, {
38
+ cause: error
39
+ });
40
+ }
41
+ throw new Error(`Pipeline step '${step}' failed with non-Error value`, {
42
+ cause: error
43
+ });
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Wraps a pipeline step with an optional `when` predicate.
3
+ * When `when` is provided, the step only runs if `when(ctx)` returns `true`.
4
+ * If `when` returns `false`, the pipeline logs `"Skipping step <name>"` and
5
+ * advances to the next step without invoking `run()`.
6
+ *
7
+ * Predicates are declared in the command constructor via `addDisableStepOption`,
8
+ * keeping skip conditions co-located with the option that controls them.
9
+ */ export class Step {
10
+ type;
11
+ when;
12
+ constructor(type, when){
13
+ this.type = type;
14
+ this.when = when;
15
+ }
16
+ }
@@ -0,0 +1,44 @@
1
+ import { InteropError } from "../errors/interop.error.js";
2
+ import { Shell } from "../shell/shell.js";
3
+ export class Docker extends Shell {
4
+ name = "docker";
5
+ program = "docker";
6
+ async build(contextDir, options = {}) {
7
+ if (contextDir == null || contextDir.trim() === "") {
8
+ throw new InteropError("Docker build context is required");
9
+ }
10
+ const args = [
11
+ "build"
12
+ ];
13
+ if (options.dockerfile) {
14
+ args.push("-f", options.dockerfile);
15
+ }
16
+ for (const tag of options.tags ?? []){
17
+ args.push("-t", tag);
18
+ }
19
+ for (const [key, value] of Object.entries(options.buildArgs ?? {})){
20
+ args.push("--build-arg", `${key}=${value}`);
21
+ }
22
+ for (const [id, env] of Object.entries(options.secrets ?? {})){
23
+ args.push("--secret", `id=${id},env=${env}`);
24
+ }
25
+ if (options.noCache) {
26
+ args.push("--no-cache");
27
+ }
28
+ if (options.pull) {
29
+ args.push("--pull");
30
+ }
31
+ args.push(contextDir);
32
+ return await this.run({
33
+ cwd: options.cwd
34
+ }, ...args);
35
+ }
36
+ async push(tag, options = {}) {
37
+ if (tag == null || tag.trim() === "") {
38
+ throw new InteropError("Docker tag is required");
39
+ }
40
+ return await this.run({
41
+ cwd: options.cwd
42
+ }, "push", tag);
43
+ }
44
+ }
@@ -0,0 +1,2 @@
1
+ export class InteropError extends Error {
2
+ }
@@ -0,0 +1,124 @@
1
+ import { InteropError } from "../errors/interop.error.js";
2
+ import { Shell } from "../shell/shell.js";
3
+ const Commands = {
4
+ stage: "stage",
5
+ tag: "tag",
6
+ add: "add",
7
+ commit: "commit",
8
+ push: "push",
9
+ listFiles: "ls-files"
10
+ };
11
+ const defaultOptions = {
12
+ cwd: "./"
13
+ };
14
+ export class Git extends Shell {
15
+ program = "git";
16
+ async getModifiedFiles(options = defaultOptions) {
17
+ const args = [
18
+ Commands.listFiles,
19
+ "--modified"
20
+ ];
21
+ const { cwd } = options;
22
+ const result = await this.run({
23
+ cwd
24
+ }, ...args);
25
+ return result.data;
26
+ }
27
+ async getBranchName(options = defaultOptions) {
28
+ const { cwd } = options;
29
+ const args = [
30
+ "rev-parse",
31
+ "--symbolic-full-name",
32
+ "--abbrev-ref",
33
+ "HEAD"
34
+ ];
35
+ const result = await this.run({
36
+ cwd
37
+ }, ...args);
38
+ return result.data[0];
39
+ }
40
+ async tag(tag, options = defaultOptions) {
41
+ const args = [
42
+ Commands.tag,
43
+ tag
44
+ ];
45
+ const { cwd } = options;
46
+ const result = await this.run({
47
+ cwd
48
+ }, ...args);
49
+ return result;
50
+ }
51
+ async pushTag(tag, options = defaultOptions) {
52
+ const { cwd, remote = "origin" } = options;
53
+ const result = await this.run({
54
+ cwd
55
+ }, Commands.push, remote, tag);
56
+ return result;
57
+ }
58
+ async commit(message, options) {
59
+ const optionsAndDefaults = {
60
+ ...defaultOptions,
61
+ ...options
62
+ };
63
+ const { cwd, files = [], all } = optionsAndDefaults;
64
+ const args = [
65
+ Commands.commit
66
+ ];
67
+ if (files.length > 0 && all) {
68
+ throw new InteropError("Cannot commit all and files at the same time");
69
+ }
70
+ if (files.length > 0) {
71
+ await this.stage({
72
+ files
73
+ });
74
+ }
75
+ if (options.all) {
76
+ args.push("-a");
77
+ }
78
+ args.push("-m", message);
79
+ const result = await this.run({
80
+ cwd
81
+ }, ...args);
82
+ return result;
83
+ }
84
+ async push(branch, options) {
85
+ const optionsAndDefaults = {
86
+ ...defaultOptions,
87
+ ...options
88
+ };
89
+ const { cwd, setUpstream } = optionsAndDefaults;
90
+ const args = [
91
+ Commands.push
92
+ ];
93
+ args.push("--set-upstream", setUpstream ?? "origin");
94
+ args.push(branch);
95
+ const result = await this.run({
96
+ cwd
97
+ }, ...args);
98
+ return result;
99
+ }
100
+ async pull(branch, options = defaultOptions) {
101
+ const { cwd } = options;
102
+ return this.run({
103
+ cwd
104
+ }, "pull", "--rebase", "origin", branch);
105
+ }
106
+ async stage(options) {
107
+ const optionsAndDefaults = {
108
+ ...defaultOptions,
109
+ ...options
110
+ };
111
+ const { cwd, files = [], all } = optionsAndDefaults;
112
+ if (all) {
113
+ await this.run({
114
+ cwd
115
+ }, Commands.stage, "-a");
116
+ return;
117
+ }
118
+ for (const file of files){
119
+ await this.run({
120
+ cwd
121
+ }, Commands.stage, file);
122
+ }
123
+ }
124
+ }
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,21 @@
1
+ // << Git >>
2
+ // << Docker >>
3
+ export * from "./docker/docker.js";
4
+ export * from "./git/git.js";
5
+ export * as git from "./git/git.types.js";
6
+ // << Node >>
7
+ export * from "./node/node.js";
8
+ // << Npm >>
9
+ export * from "./npm/npm.js";
10
+ export * as npm from "./npm/npm.types.js";
11
+ // << Pnpm >>
12
+ export * from "./pnpm/pnpm.js";
13
+ export * as pnpm from "./pnpm/pnpm.types.js";
14
+ // << Shell >>
15
+ export * from "./shell/shell.js";
16
+ export * as shell from "./shell/shell.types.js";
17
+ export * from "./types/detect-package-manager.js";
18
+ export * from "./types/package-manager.js";
19
+ // << Yarn >>
20
+ export * from "./yarn/yarn.js";
21
+ export * as yarn from "./yarn/yarn.types.js";
@@ -0,0 +1 @@
1
+ export * from "./node.js";
@@ -0,0 +1,35 @@
1
+ import { spawn } from "node:child_process";
2
+ import { Shell } from "../shell/shell.js";
3
+ export class Node extends Shell {
4
+ program = "node";
5
+ async runScript(script, ...args) {
6
+ const spawnOpt = {
7
+ cwd: ".",
8
+ stdio: "inherit",
9
+ env: {
10
+ ...process.env
11
+ }
12
+ };
13
+ return new Promise((resolve, reject)=>{
14
+ const proc = spawn("node", [
15
+ script,
16
+ ...args
17
+ ], spawnOpt);
18
+ proc.on("exit", (code)=>{
19
+ if (code !== 0) {
20
+ reject();
21
+ }
22
+ resolve(null);
23
+ });
24
+ proc.on("close", (code)=>{
25
+ resolve(null);
26
+ if (code === 0) {
27
+ resolve({
28
+ message: `${script} completed`
29
+ });
30
+ }
31
+ reject(`Running '${script}' failed with code ${code}`);
32
+ });
33
+ });
34
+ }
35
+ }
@@ -0,0 +1,180 @@
1
+ import { InteropError } from "../errors/interop.error.js";
2
+ import { Shell } from "../shell/shell.js";
3
+ const Commands = {
4
+ publish: "publish",
5
+ version: "version",
6
+ link: "link",
7
+ install: "install"
8
+ };
9
+ export class Npm extends Shell {
10
+ name = "npm";
11
+ program = "npm";
12
+ async publish(directory, options = {
13
+ channel: "beta"
14
+ }) {
15
+ const { cwd, dryRun, skipIfPublished, channel, authToken, otp, provenance } = options;
16
+ if (directory == null) {
17
+ throw new InteropError("Directory is required");
18
+ }
19
+ if (skipIfPublished && !dryRun) {
20
+ const alreadyPublished = await this.isPublished(directory, {
21
+ cwd
22
+ });
23
+ if (alreadyPublished) {
24
+ return {
25
+ message: `Skipping publish — version already exists on registry`,
26
+ data: []
27
+ };
28
+ }
29
+ }
30
+ const args = [
31
+ Commands.publish,
32
+ directory
33
+ ];
34
+ let tmpUserConfigPath;
35
+ args.push("--tag", channel ?? "beta");
36
+ if (provenance) {
37
+ args.push("--provenance");
38
+ }
39
+ // Explicit --token (local bootstrap). OIDC publish must not inherit cwd .npmrc / NODE_AUTH_TOKEN.
40
+ if (authToken?.trim()) {
41
+ tmpUserConfigPath = await this.createTempUserConfig(authToken.trim());
42
+ args.push("--userconfig", tmpUserConfigPath);
43
+ }
44
+ if (dryRun) {
45
+ args.push("--dry-run");
46
+ }
47
+ const env = {
48
+ ...process.env
49
+ };
50
+ if (!authToken?.trim()) {
51
+ delete env.NODE_AUTH_TOKEN;
52
+ delete env.NPM_TOKEN;
53
+ env.NPM_CONFIG_USERCONFIG = "/dev/null";
54
+ }
55
+ if (otp) {
56
+ env.NPM_CONFIG_OTP = otp;
57
+ }
58
+ try {
59
+ return await this.run({
60
+ cwd,
61
+ env
62
+ }, ...args);
63
+ } catch (error) {
64
+ if (skipIfPublished && !dryRun && isAlreadyPublishedError(error)) {
65
+ return {
66
+ message: `Skipping publish — version already exists on registry`,
67
+ data: []
68
+ };
69
+ }
70
+ throw error;
71
+ } finally{
72
+ if (tmpUserConfigPath) {
73
+ await this.removeTempUserConfig(tmpUserConfigPath);
74
+ }
75
+ }
76
+ }
77
+ /**
78
+ * @description Runs in the directory of the package
79
+ * @param options
80
+ * @returns
81
+ */ async version(versionType, options) {
82
+ const { cwd, noTag, preid } = options;
83
+ const args = [
84
+ Commands.version,
85
+ versionType
86
+ ];
87
+ if (noTag) {
88
+ args.push("--no-git-tag-version");
89
+ }
90
+ if (preid) {
91
+ args.push("--preid", preid);
92
+ }
93
+ return this.run({
94
+ cwd
95
+ }, ...args);
96
+ }
97
+ async link(directory, options = {
98
+ cwd: "./"
99
+ }) {
100
+ const { cwd } = options;
101
+ const args = [
102
+ Commands.link,
103
+ directory
104
+ ];
105
+ return this.run({
106
+ cwd
107
+ }, ...args);
108
+ }
109
+ async install(options = {
110
+ cwd: "./"
111
+ }) {
112
+ const { cwd } = options;
113
+ return this.run({
114
+ cwd
115
+ }, Commands.install);
116
+ }
117
+ /**
118
+ * Install only `dependencies` as real folders: `--omit=dev` skips devDependencies and
119
+ * `--no-bin-links` skips the `.bin` symlinks, so the result holds no symlinks at all.
120
+ */ async installProduction(options = {
121
+ cwd: "./"
122
+ }) {
123
+ const { cwd } = options;
124
+ return this.run({
125
+ cwd
126
+ }, Commands.install, "--omit=dev", "--no-bin-links", "--no-audit", "--no-fund", "--loglevel=error");
127
+ }
128
+ async syncLockFile(options = {
129
+ cwd: "./"
130
+ }) {
131
+ const { cwd } = options;
132
+ return this.run({
133
+ cwd
134
+ }, Commands.install, "--package-lock-only", "--ignore-scripts");
135
+ }
136
+ /**
137
+ * True when package@version exists on the registry.
138
+ * Uses ambient npm config (cwd `.npmrc`); do not pass tokens on argv.
139
+ */ async isPublished(directory, options) {
140
+ const { readFileSync } = await import("node:fs");
141
+ const { join } = await import("node:path");
142
+ try {
143
+ const pkgJson = JSON.parse(readFileSync(join(directory, "package.json"), "utf8"));
144
+ const spec = `${pkgJson.name}@${pkgJson.version}`;
145
+ await this.run(options, "view", spec, "version");
146
+ return true;
147
+ } catch {
148
+ return false;
149
+ }
150
+ }
151
+ async createTempUserConfig(authToken) {
152
+ const { mkdtemp, writeFile } = await import("node:fs/promises");
153
+ const { tmpdir } = await import("node:os");
154
+ const { join } = await import("node:path");
155
+ const tempDir = await mkdtemp(join(tmpdir(), "decohere-npmrc-"));
156
+ const npmrcPath = join(tempDir, ".npmrc");
157
+ const npmrc = [
158
+ "registry=https://registry.npmjs.org/",
159
+ "always-auth=true",
160
+ `//registry.npmjs.org/:_authToken=${authToken}`
161
+ ].join("\n");
162
+ await writeFile(npmrcPath, `${npmrc}\n`, {
163
+ mode: 0o600
164
+ });
165
+ return npmrcPath;
166
+ }
167
+ async removeTempUserConfig(npmrcPath) {
168
+ const { rm } = await import("node:fs/promises");
169
+ const { dirname } = await import("node:path");
170
+ const dir = dirname(npmrcPath);
171
+ await rm(dir, {
172
+ recursive: true,
173
+ force: true
174
+ });
175
+ }
176
+ }
177
+ function isAlreadyPublishedError(error) {
178
+ const message = error instanceof Error ? error.message : String(error);
179
+ return /cannot publish over the previously published versions/i.test(message);
180
+ }
@@ -0,0 +1,6 @@
1
+ export const VersionTypes = {
2
+ major: "major",
3
+ minor: "minor",
4
+ patch: "patch",
5
+ prerelease: "prerelease"
6
+ };
@@ -0,0 +1,24 @@
1
+ import { Shell } from "../shell/shell.js";
2
+ const Commands = {
3
+ install: "install"
4
+ };
5
+ export class Pnpm extends Shell {
6
+ name = "pnpm";
7
+ program = "pnpm";
8
+ async install(options = {
9
+ cwd: "./"
10
+ }) {
11
+ const { cwd } = options;
12
+ return this.run({
13
+ cwd
14
+ }, Commands.install);
15
+ }
16
+ async syncLockFile(options = {
17
+ cwd: "./"
18
+ }) {
19
+ const { cwd } = options;
20
+ return this.run({
21
+ cwd
22
+ }, Commands.install, "--lockfile-only", "--ignore-scripts");
23
+ }
24
+ }
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,35 @@
1
+ function fields(args) {
2
+ const positional = [];
3
+ const flags = {};
4
+ for(let i = 0; i < args.length; i++){
5
+ const arg = args[i];
6
+ if (arg === "--") {
7
+ positional.push(...args.slice(i + 1));
8
+ break;
9
+ }
10
+ if (arg.startsWith("--")) {
11
+ const body = arg.slice(2);
12
+ const eq = body.indexOf("=");
13
+ if (eq !== -1) {
14
+ flags[body.slice(0, eq)] = body.slice(eq + 1);
15
+ continue;
16
+ }
17
+ const next = args[i + 1];
18
+ if (next != null && !next.startsWith("-")) {
19
+ flags[body] = next;
20
+ i += 1;
21
+ } else {
22
+ flags[body] = true;
23
+ }
24
+ continue;
25
+ }
26
+ positional.push(arg);
27
+ }
28
+ return {
29
+ _: positional,
30
+ ...flags
31
+ };
32
+ }
33
+ export const shellArgv = {
34
+ fields
35
+ };
@@ -0,0 +1,95 @@
1
+ import { spawn } from "node:child_process";
2
+ import { scribe } from "@decohere/scribe";
3
+ import { InteropError } from "../errors/interop.error.js";
4
+ import { shellArgv } from "./shell.argv.js";
5
+ export class Shell {
6
+ async run(options, ...args) {
7
+ const logger = scribe.logger(Shell.name);
8
+ const argv = args ?? [];
9
+ const argvFields = shellArgv.fields(argv);
10
+ const positionals = Array.isArray(argvFields._) ? argvFields._ : [];
11
+ const commandName = [
12
+ this.program,
13
+ ...positionals
14
+ ].join(" ").trim();
15
+ logger.info("Running", {
16
+ program: this.program,
17
+ args: argvFields
18
+ });
19
+ return new Promise((resolve, reject)=>{
20
+ let settled = false;
21
+ const resolveOnce = (response)=>{
22
+ if (settled) {
23
+ return;
24
+ }
25
+ settled = true;
26
+ resolve(response);
27
+ };
28
+ const rejectOnce = (error)=>{
29
+ if (settled) {
30
+ return;
31
+ }
32
+ settled = true;
33
+ reject(error);
34
+ };
35
+ const { cwd, env } = options;
36
+ const spawnOpt = {
37
+ cwd: cwd ?? ".",
38
+ stdio: [
39
+ "inherit",
40
+ "pipe",
41
+ "pipe"
42
+ ],
43
+ env: env ?? {
44
+ ...process.env
45
+ }
46
+ };
47
+ const proc = spawn(this.program, argv, spawnOpt);
48
+ const responseData = [];
49
+ const errorData = [];
50
+ proc.on("close", (code, signal)=>{
51
+ if (code === 0) {
52
+ resolveOnce({
53
+ message: `${commandName} completed`,
54
+ data: responseData
55
+ });
56
+ return;
57
+ }
58
+ const stderr = errorData.join("\n").trim();
59
+ const stdout = responseData.join("\n").trim();
60
+ const exitCodeText = code == null ? "unknown" : String(code);
61
+ const signalText = signal ? ` signal ${signal}` : "";
62
+ const base = `Running '${commandName}' failed with code ${exitCodeText}${signalText}`;
63
+ const details = [
64
+ stderr ? `stderr:\n${stderr}` : "",
65
+ !stderr && stdout ? `stdout:\n${stdout}` : ""
66
+ ].filter(Boolean).join("\n");
67
+ rejectOnce(new InteropError(details ? `${base}\n${details}` : base));
68
+ });
69
+ proc.on("error", (err)=>{
70
+ rejectOnce(err);
71
+ });
72
+ proc.stdout.on("error", (err)=>{
73
+ rejectOnce(err);
74
+ });
75
+ proc.stdout.on("data", (data)=>{
76
+ const lines = this.parseStream(data);
77
+ console.log(data.toString());
78
+ responseData.push(...lines);
79
+ });
80
+ proc.stderr?.on("error", (err)=>{
81
+ rejectOnce(err);
82
+ });
83
+ proc.stderr?.on("data", (data)=>{
84
+ const lines = this.parseStream(data);
85
+ console.error(data.toString());
86
+ errorData.push(...lines);
87
+ });
88
+ });
89
+ }
90
+ parseStream(data) {
91
+ const dataStr = data.toString();
92
+ const lines = dataStr.split("\n").filter((l)=>l !== "");
93
+ return lines;
94
+ }
95
+ }
@@ -0,0 +1 @@
1
+ export { };