@quadnix/octo 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/README.md +108 -21
  2. package/dist/app.type.d.ts +141 -22
  3. package/dist/app.type.js.map +1 -1
  4. package/dist/decorators/model.decorator.d.ts +3 -5
  5. package/dist/decorators/model.decorator.js +1 -6
  6. package/dist/decorators/model.decorator.js.map +1 -1
  7. package/dist/decorators/on-event.decorator.d.ts +2 -2
  8. package/dist/decorators/on-event.decorator.js.map +1 -1
  9. package/dist/decorators/resource.decorator.d.ts +50 -1
  10. package/dist/decorators/resource.decorator.js +38 -1
  11. package/dist/decorators/resource.decorator.js.map +1 -1
  12. package/dist/errors/schema.error.d.ts +8 -1
  13. package/dist/errors/schema.error.js +5 -1
  14. package/dist/errors/schema.error.js.map +1 -1
  15. package/dist/errors/terraform.error.d.ts +4 -3
  16. package/dist/errors/terraform.error.js +4 -3
  17. package/dist/errors/terraform.error.js.map +1 -1
  18. package/dist/errors/transaction.error.d.ts +32 -2
  19. package/dist/errors/transaction.error.js +22 -0
  20. package/dist/errors/transaction.error.js.map +1 -1
  21. package/dist/events/action.event.d.ts +8 -2
  22. package/dist/events/action.event.js +2 -2
  23. package/dist/events/action.event.js.map +1 -1
  24. package/dist/events/command.event.d.ts +43 -0
  25. package/dist/events/command.event.js +33 -0
  26. package/dist/events/command.event.js.map +1 -0
  27. package/dist/events/event.model.d.ts +7 -5
  28. package/dist/events/event.model.js +5 -3
  29. package/dist/events/event.model.js.map +1 -1
  30. package/dist/events/hook/commit.hook.event.d.ts +1 -1
  31. package/dist/events/hook/commit.hook.event.js.map +1 -1
  32. package/dist/events/hook/hook.event.d.ts +1 -1
  33. package/dist/events/hook/hook.event.js.map +1 -1
  34. package/dist/events/hook/model.hook.event.d.ts +1 -1
  35. package/dist/events/hook/model.hook.event.js.map +1 -1
  36. package/dist/events/hook/resource.hook.event.d.ts +1 -1
  37. package/dist/events/hook/resource.hook.event.js.map +1 -1
  38. package/dist/events/index.d.ts +2 -0
  39. package/dist/events/index.js +2 -0
  40. package/dist/events/index.js.map +1 -1
  41. package/dist/events/mode-result.event.d.ts +1 -1
  42. package/dist/events/mode-result.event.js.map +1 -1
  43. package/dist/events/mode.event.d.ts +8 -4
  44. package/dist/events/mode.event.js.map +1 -1
  45. package/dist/events/module.event.d.ts +7 -3
  46. package/dist/events/module.event.js +3 -2
  47. package/dist/events/module.event.js.map +1 -1
  48. package/dist/events/registration.event.d.ts +1 -1
  49. package/dist/events/registration.event.js.map +1 -1
  50. package/dist/events/serialization.event.d.ts +1 -1
  51. package/dist/events/serialization.event.js.map +1 -1
  52. package/dist/events/state.event.d.ts +102 -0
  53. package/dist/events/state.event.js +69 -0
  54. package/dist/events/state.event.js.map +1 -0
  55. package/dist/events/terraform.event.d.ts +37 -1
  56. package/dist/events/terraform.event.js +24 -0
  57. package/dist/events/terraform.event.js.map +1 -1
  58. package/dist/events/transaction.event.d.ts +3 -3
  59. package/dist/events/transaction.event.js +1 -1
  60. package/dist/events/transaction.event.js.map +1 -1
  61. package/dist/functions/container/container.js +1 -1
  62. package/dist/functions/container/container.js.map +1 -1
  63. package/dist/functions/container/test-container.js +2 -2
  64. package/dist/functions/container/test-container.js.map +1 -1
  65. package/dist/functions/dependency/dependency.d.ts +9 -22
  66. package/dist/functions/dependency/dependency.js +5 -1
  67. package/dist/functions/dependency/dependency.js.map +1 -1
  68. package/dist/functions/diff/diff.d.ts +14 -7
  69. package/dist/functions/diff/diff.js.map +1 -1
  70. package/dist/functions/node/node-action.abstract.d.ts +8 -10
  71. package/dist/functions/node/node-action.abstract.js +10 -16
  72. package/dist/functions/node/node-action.abstract.js.map +1 -1
  73. package/dist/functions/node/node.abstract.js +21 -10
  74. package/dist/functions/node/node.abstract.js.map +1 -1
  75. package/dist/functions/node/node.interface.d.ts +2 -1
  76. package/dist/functions/schema/schema.js +1 -1
  77. package/dist/functions/schema/schema.js.map +1 -1
  78. package/dist/index.d.ts +8 -6
  79. package/dist/index.js +6 -4
  80. package/dist/index.js.map +1 -1
  81. package/dist/index.type.d.ts +5 -0
  82. package/dist/index.type.js +2 -0
  83. package/dist/index.type.js.map +1 -0
  84. package/dist/main.d.ts +4 -3
  85. package/dist/main.js +27 -11
  86. package/dist/main.js.map +1 -1
  87. package/dist/models/account/account.model.d.ts +6 -0
  88. package/dist/models/account/account.model.js +16 -0
  89. package/dist/models/account/account.model.js.map +1 -1
  90. package/dist/models/app/app.model.d.ts +0 -10
  91. package/dist/models/app/app.model.js +0 -30
  92. package/dist/models/app/app.model.js.map +1 -1
  93. package/dist/models/deployment/deployment.schema.d.ts +4 -0
  94. package/dist/models/deployment/deployment.schema.js +4 -0
  95. package/dist/models/deployment/deployment.schema.js.map +1 -1
  96. package/dist/models/environment/environment.model.d.ts +2 -2
  97. package/dist/models/environment/environment.model.js +2 -2
  98. package/dist/models/execution/execution.model.d.ts +1 -1
  99. package/dist/models/execution/execution.model.js +1 -1
  100. package/dist/models/image/image.model.d.ts +4 -3
  101. package/dist/models/image/image.model.js +7 -6
  102. package/dist/models/image/image.model.js.map +1 -1
  103. package/dist/models/model.abstract.js +1 -1
  104. package/dist/models/model.abstract.js.map +1 -1
  105. package/dist/models/pipeline/pipeline.model.d.ts +1 -1
  106. package/dist/models/pipeline/pipeline.model.js +1 -1
  107. package/dist/models/server/server.model.d.ts +2 -2
  108. package/dist/models/server/server.model.js +2 -2
  109. package/dist/models/service/service.model.d.ts +28 -11
  110. package/dist/models/service/service.model.js +56 -16
  111. package/dist/models/service/service.model.js.map +1 -1
  112. package/dist/models/service/service.schema.d.ts +46 -2
  113. package/dist/models/service/service.schema.js +54 -2
  114. package/dist/models/service/service.schema.js.map +1 -1
  115. package/dist/modes/commit.mode.d.ts +2 -2
  116. package/dist/modes/commit.mode.js +2 -2
  117. package/dist/modes/generate.mode.d.ts +2 -1
  118. package/dist/modes/generate.mode.js +3 -2
  119. package/dist/modes/generate.mode.js.map +1 -1
  120. package/dist/modes/run-action.mode.d.ts +1 -1
  121. package/dist/modes/run-action.mode.js +1 -1
  122. package/dist/modes/validate.mode.d.ts +24 -0
  123. package/dist/modes/validate.mode.js +89 -11
  124. package/dist/modes/validate.mode.js.map +1 -1
  125. package/dist/modules/module.container.d.ts +7 -1
  126. package/dist/modules/module.container.js +41 -5
  127. package/dist/modules/module.container.js.map +1 -1
  128. package/dist/modules/test-module.container.js +35 -83
  129. package/dist/modules/test-module.container.js.map +1 -1
  130. package/dist/overlays/overlay.abstract.js +1 -1
  131. package/dist/overlays/overlay.abstract.js.map +1 -1
  132. package/dist/resources/resource-action.interface.d.ts +4 -2
  133. package/dist/resources/resource.abstract.d.ts +50 -8
  134. package/dist/resources/resource.abstract.js +63 -32
  135. package/dist/resources/resource.abstract.js.map +1 -1
  136. package/dist/resources/resource.interface.d.ts +0 -2
  137. package/dist/resources/resource.schema.d.ts +11 -1
  138. package/dist/resources/resource.schema.js +11 -1
  139. package/dist/resources/resource.schema.js.map +1 -1
  140. package/dist/services/event/event.service.d.ts +2 -2
  141. package/dist/services/event/event.service.js.map +1 -1
  142. package/dist/services/input/input.service.d.ts +30 -2
  143. package/dist/services/input/input.service.js +71 -4
  144. package/dist/services/input/input.service.js.map +1 -1
  145. package/dist/services/serialization/model/model-serialization.service.d.ts +4 -6
  146. package/dist/services/serialization/model/model-serialization.service.js +20 -17
  147. package/dist/services/serialization/model/model-serialization.service.js.map +1 -1
  148. package/dist/services/serialization/resource/resource-serialization.service.d.ts +7 -6
  149. package/dist/services/serialization/resource/resource-serialization.service.js +25 -12
  150. package/dist/services/serialization/resource/resource-serialization.service.js.map +1 -1
  151. package/dist/services/state-management/local.state-provider.d.ts +25 -9
  152. package/dist/services/state-management/local.state-provider.js +127 -21
  153. package/dist/services/state-management/local.state-provider.js.map +1 -1
  154. package/dist/services/state-management/remote.state-provider.d.ts +216 -0
  155. package/dist/services/state-management/remote.state-provider.js +645 -0
  156. package/dist/services/state-management/remote.state-provider.js.map +1 -0
  157. package/dist/services/state-management/state-management.service.d.ts +83 -40
  158. package/dist/services/state-management/state-management.service.js +130 -26
  159. package/dist/services/state-management/state-management.service.js.map +1 -1
  160. package/dist/services/state-management/state-provider.interface.d.ts +50 -9
  161. package/dist/services/state-management/state-provider.interface.js +14 -1
  162. package/dist/services/state-management/state-provider.interface.js.map +1 -1
  163. package/dist/services/state-management/terraform-state.service.d.ts +32 -9
  164. package/dist/services/state-management/terraform-state.service.js +64 -21
  165. package/dist/services/state-management/terraform-state.service.js.map +1 -1
  166. package/dist/services/state-management/test.state-provider.d.ts +11 -10
  167. package/dist/services/state-management/test.state-provider.js +35 -14
  168. package/dist/services/state-management/test.state-provider.js.map +1 -1
  169. package/dist/services/terraform/terraform.service.d.ts +57 -3
  170. package/dist/services/terraform/terraform.service.js +95 -8
  171. package/dist/services/terraform/terraform.service.js.map +1 -1
  172. package/dist/services/terraform/terraform.type.js +1 -1
  173. package/dist/services/terraform/terraform.type.js.map +1 -1
  174. package/dist/services/transaction/transaction.service.d.ts +29 -5
  175. package/dist/services/transaction/transaction.service.js +198 -34
  176. package/dist/services/transaction/transaction.service.js.map +1 -1
  177. package/dist/services/validation/validation.service.d.ts +2 -2
  178. package/dist/{functions → utilities}/diff/diff.utility.d.ts +2 -1
  179. package/dist/{functions → utilities}/diff/diff.utility.js +4 -3
  180. package/dist/utilities/diff/diff.utility.js.map +1 -0
  181. package/dist/utilities/file/file.utility.d.ts +6 -7
  182. package/dist/utilities/file/file.utility.js +13 -68
  183. package/dist/utilities/file/file.utility.js.map +1 -1
  184. package/dist/utilities/hcl/hcl.utility.d.ts +83 -16
  185. package/dist/utilities/hcl/hcl.utility.js +200 -27
  186. package/dist/utilities/hcl/hcl.utility.js.map +1 -1
  187. package/dist/utilities/http/http.utility.d.ts +57 -0
  188. package/dist/utilities/http/http.utility.js +98 -0
  189. package/dist/utilities/http/http.utility.js.map +1 -0
  190. package/dist/utilities/string/string.utility.d.ts +23 -3
  191. package/dist/utilities/string/string.utility.js +29 -3
  192. package/dist/utilities/string/string.utility.js.map +1 -1
  193. package/dist/utilities/terraform/terraform.utility.d.ts +70 -21
  194. package/dist/utilities/terraform/terraform.utility.js +255 -66
  195. package/dist/utilities/terraform/terraform.utility.js.map +1 -1
  196. package/dist/utilities/test-helpers/test-classes.d.ts +19 -0
  197. package/dist/utilities/test-helpers/test-classes.js +22 -0
  198. package/dist/utilities/test-helpers/test-classes.js.map +1 -1
  199. package/dist/utilities/test-helpers/test-models.d.ts +8 -1
  200. package/dist/utilities/test-helpers/test-models.js +25 -12
  201. package/dist/utilities/test-helpers/test-models.js.map +1 -1
  202. package/dist/utilities/test-helpers/test-modes.d.ts +1 -1
  203. package/dist/utilities/test-helpers/test-modes.js +36 -13
  204. package/dist/utilities/test-helpers/test-modes.js.map +1 -1
  205. package/dist/utilities/test-helpers/test-modules.d.ts +6 -0
  206. package/dist/utilities/test-helpers/test-modules.js +6 -0
  207. package/dist/utilities/test-helpers/test-modules.js.map +1 -1
  208. package/dist/utilities/test-helpers/test-overlays.d.ts +3 -1
  209. package/dist/utilities/test-helpers/test-overlays.js +8 -2
  210. package/dist/utilities/test-helpers/test-overlays.js.map +1 -1
  211. package/dist/utilities/test-helpers/test-resources.d.ts +4 -2
  212. package/dist/utilities/test-helpers/test-resources.js +22 -20
  213. package/dist/utilities/test-helpers/test-resources.js.map +1 -1
  214. package/package.json +7 -2
  215. package/dist/functions/diff/diff.utility.js.map +0 -1
  216. package/dist/services/state-management/file-app-lock.utility.d.ts +0 -43
  217. package/dist/services/state-management/file-app-lock.utility.js +0 -124
  218. package/dist/services/state-management/file-app-lock.utility.js.map +0 -1
  219. package/dist/services/state-management/local-encryption.state-provider.d.ts +0 -71
  220. package/dist/services/state-management/local-encryption.state-provider.js +0 -116
  221. package/dist/services/state-management/local-encryption.state-provider.js.map +0 -1
@@ -1,43 +0,0 @@
1
- /**
2
- * The app lock, kept as a file on disk. Shared by the state providers that keep state in a directory.
3
- *
4
- * The lock is taken with an exclusive create, which the filesystem resolves atomically: of two
5
- * processes racing for the same path, exactly one succeeds. Reading first and writing second would
6
- * let both believe they hold it.
7
- *
8
- * The lock never expires, so a run that died holding one leaves it held until a person releases it
9
- * with `octo unlock --force`. That decision turns on whether the holder is still working, so the
10
- * record carries the time it was taken and a blocked run is told how long it has been held.
11
- *
12
- * @internal
13
- */
14
- export declare class FileAppLockUtility {
15
- /**
16
- * @internal
17
- */
18
- static getAppLock(lockFilePath: string): Promise<string | undefined>;
19
- /**
20
- * @internal
21
- */
22
- static isAppLocked(lockFilePath: string, lockId: string): Promise<boolean>;
23
- /**
24
- * @internal
25
- */
26
- static lockApp(lockFilePath: string): Promise<{
27
- lockId: string;
28
- }>;
29
- /**
30
- * @internal
31
- */
32
- static unlockApp(lockFilePath: string, lockId: string): Promise<void>;
33
- /**
34
- * How long the lock has been held, as a short readable span. Undefined when the recorded time
35
- * cannot be read as one, so a broken value is left out rather than reported as a negative age.
36
- */
37
- private static describeAge;
38
- /**
39
- * The lock file's record, or undefined when no lock is held. A file holding an id and nothing else
40
- * is a lock taken before the record carried a time, and reads as that id with no age.
41
- */
42
- private static readLock;
43
- }
@@ -1,124 +0,0 @@
1
- import { randomUUID } from 'node:crypto';
2
- import { readFile, rm, writeFile } from 'node:fs/promises';
3
- import { TransactionError } from '../../errors/index.js';
4
- /**
5
- * The app lock, kept as a file on disk. Shared by the state providers that keep state in a directory.
6
- *
7
- * The lock is taken with an exclusive create, which the filesystem resolves atomically: of two
8
- * processes racing for the same path, exactly one succeeds. Reading first and writing second would
9
- * let both believe they hold it.
10
- *
11
- * The lock never expires, so a run that died holding one leaves it held until a person releases it
12
- * with `octo unlock --force`. That decision turns on whether the holder is still working, so the
13
- * record carries the time it was taken and a blocked run is told how long it has been held.
14
- *
15
- * @internal
16
- */
17
- export class FileAppLockUtility {
18
- /**
19
- * @internal
20
- */
21
- static async getAppLock(lockFilePath) {
22
- return (await this.readLock(lockFilePath))?.lockId;
23
- }
24
- /**
25
- * @internal
26
- */
27
- static async isAppLocked(lockFilePath, lockId) {
28
- const existingLockId = await this.getAppLock(lockFilePath);
29
- if (!existingLockId) {
30
- return false;
31
- }
32
- if (existingLockId !== lockId) {
33
- throw new TransactionError('Invalid lock ID!');
34
- }
35
- return true;
36
- }
37
- /**
38
- * @internal
39
- */
40
- static async lockApp(lockFilePath) {
41
- const lockId = randomUUID();
42
- const record = { lockId, startedAt: new Date().toISOString() };
43
- try {
44
- await writeFile(lockFilePath, JSON.stringify(record), { flag: 'wx' });
45
- }
46
- catch (error) {
47
- if (error.code === 'EEXIST') {
48
- // The holder is read back and reported, so a blocked run can be told what to break without a
49
- // separate command to ask, and how long it has been held without one either.
50
- const holder = await this.readLock(lockFilePath);
51
- const heldFor = holder?.startedAt ? this.describeAge(holder.startedAt) : undefined;
52
- throw new TransactionError(`App already locked with lock ID "${holder?.lockId}"${heldFor ? `, held for ${heldFor}` : ''}!`);
53
- }
54
- throw error;
55
- }
56
- return { lockId };
57
- }
58
- /**
59
- * @internal
60
- */
61
- static async unlockApp(lockFilePath, lockId) {
62
- const existingLockId = await this.getAppLock(lockFilePath);
63
- if (!existingLockId) {
64
- return;
65
- }
66
- if (existingLockId !== lockId) {
67
- throw new TransactionError('Invalid lock ID!');
68
- }
69
- await rm(lockFilePath, { force: true });
70
- }
71
- /**
72
- * How long the lock has been held, as a short readable span. Undefined when the recorded time
73
- * cannot be read as one, so a broken value is left out rather than reported as a negative age.
74
- */
75
- static describeAge(startedAt) {
76
- const heldForMs = Date.now() - Date.parse(startedAt);
77
- if (!Number.isFinite(heldForMs) || heldForMs < 0) {
78
- return undefined;
79
- }
80
- const seconds = Math.floor(heldForMs / 1000);
81
- if (seconds < 60) {
82
- return `${seconds}s`;
83
- }
84
- const minutes = Math.floor(seconds / 60);
85
- if (minutes < 60) {
86
- return `${minutes}m`;
87
- }
88
- const hours = Math.floor(minutes / 60);
89
- if (hours < 24) {
90
- return `${hours}h ${minutes % 60}m`;
91
- }
92
- return `${Math.floor(hours / 24)}d ${hours % 24}h`;
93
- }
94
- /**
95
- * The lock file's record, or undefined when no lock is held. A file holding an id and nothing else
96
- * is a lock taken before the record carried a time, and reads as that id with no age.
97
- */
98
- static async readLock(lockFilePath) {
99
- let contents;
100
- try {
101
- contents = (await readFile(lockFilePath, 'utf-8')).trim();
102
- }
103
- catch (error) {
104
- if (error.code === 'ENOENT') {
105
- return undefined;
106
- }
107
- throw error;
108
- }
109
- if (!contents) {
110
- return undefined;
111
- }
112
- if (!contents.startsWith('{')) {
113
- return { lockId: contents };
114
- }
115
- try {
116
- const record = JSON.parse(contents);
117
- return typeof record.lockId === 'string' ? record : { lockId: contents };
118
- }
119
- catch (error) {
120
- return { lockId: contents };
121
- }
122
- }
123
- }
124
- //# sourceMappingURL=file-app-lock.utility.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"file-app-lock.utility.js","sourceRoot":"","sources":["../../../src/services/state-management/file-app-lock.utility.ts"],"names":[],"mappings":"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"}
@@ -1,71 +0,0 @@
1
- import type { IStateProvider } from './state-provider.interface.js';
2
- /**
3
- * Keeps state in a local directory, encrypted, with an `.enc` suffix.
4
- *
5
- * The point is that the resulting files are safe to commit to version control, which gives a small
6
- * team shared state without any infrastructure to run.
7
- *
8
- * @example
9
- * ```ts
10
- * await octo.initialize(new LocalEncryptionStateProvider('./infrastructure', process.env.OCTO_KEY!));
11
- * ```
12
- *
13
- * @group Services/State Management
14
- *
15
- * @see Techniques for [State Providers](/docs/techniques/state-providers).
16
- */
17
- export declare class LocalEncryptionStateProvider implements IStateProvider {
18
- private readonly encryptionKey;
19
- private readonly localStateDirectoryPath;
20
- private readonly lockFilePath;
21
- /**
22
- * @param localStateDirectoryPath The directory state files are written into.
23
- * @param encryptionKey The key state is encrypted with. It must be at least 3 characters.
24
- * @throws {@link TransactionError} If the key is too weak.
25
- */
26
- constructor(localStateDirectoryPath: string, encryptionKey: string);
27
- /**
28
- * Deletes a state file. Deleting one that is not there is not an error.
29
- */
30
- deleteState(stateFileName: string): Promise<void>;
31
- /**
32
- * The id of the lock currently held, or `undefined` when the app is unlocked. The lock file is not
33
- * encrypted - a lock id identifies a run, and reveals nothing about the state it guards.
34
- */
35
- getAppLock(): Promise<string | undefined>;
36
- /**
37
- * Reads a state file.
38
- *
39
- * @throws {@link TransactionError} With the message `No state found!` when the file does not exist.
40
- */
41
- getState(stateFileName: string): Promise<Buffer>;
42
- /**
43
- * Whether `lockId` is the lock currently held.
44
- *
45
- * @throws {@link TransactionError} With the message `Invalid lock ID!` when a different lock is held.
46
- */
47
- isAppLocked(lockId: string): Promise<boolean>;
48
- /**
49
- * The names of the state files whose name starts with `prefix`, with the `.enc` suffix removed so
50
- * a caller can read them back by the name it knows.
51
- */
52
- listStates(prefix: string): Promise<string[]>;
53
- /**
54
- * Takes the app lock, writing its id into `local-state.lock` beside the state files.
55
- *
56
- * @throws {@link TransactionError} When a lock is held, naming the id that holds it.
57
- */
58
- lockApp(): Promise<{
59
- lockId: string;
60
- }>;
61
- /**
62
- * Writes a state file, overwriting whatever was there.
63
- */
64
- saveState(stateFileName: string, data: Buffer): Promise<void>;
65
- /**
66
- * Releases the app lock by deleting the lock file.
67
- *
68
- * @throws {@link TransactionError} With the message `Invalid lock ID!` when a different lock is held.
69
- */
70
- unlockApp(lockId: string): Promise<void>;
71
- }
@@ -1,116 +0,0 @@
1
- import { readdir, rm } from 'fs/promises';
2
- import { join, resolve } from 'path';
3
- import { TransactionError } from '../../errors/index.js';
4
- import { FileUtility } from '../../utilities/file/file.utility.js';
5
- import { FileAppLockUtility } from './file-app-lock.utility.js';
6
- /**
7
- * Keeps state in a local directory, encrypted, with an `.enc` suffix.
8
- *
9
- * The point is that the resulting files are safe to commit to version control, which gives a small
10
- * team shared state without any infrastructure to run.
11
- *
12
- * @example
13
- * ```ts
14
- * await octo.initialize(new LocalEncryptionStateProvider('./infrastructure', process.env.OCTO_KEY!));
15
- * ```
16
- *
17
- * @group Services/State Management
18
- *
19
- * @see Techniques for [State Providers](/docs/techniques/state-providers).
20
- */
21
- export class LocalEncryptionStateProvider {
22
- /**
23
- * @param localStateDirectoryPath The directory state files are written into.
24
- * @param encryptionKey The key state is encrypted with. It must be at least 3 characters.
25
- * @throws {@link TransactionError} If the key is too weak.
26
- */
27
- constructor(localStateDirectoryPath, encryptionKey) {
28
- if (encryptionKey.length < 3) {
29
- throw new TransactionError('Selected encryption key is too weak!');
30
- }
31
- this.encryptionKey = encryptionKey;
32
- this.localStateDirectoryPath = resolve(localStateDirectoryPath);
33
- this.lockFilePath = join(this.localStateDirectoryPath, 'local-state.lock');
34
- }
35
- /**
36
- * Deletes a state file. Deleting one that is not there is not an error.
37
- */
38
- async deleteState(stateFileName) {
39
- await rm(join(this.localStateDirectoryPath, stateFileName + '.enc'), { force: true });
40
- }
41
- /**
42
- * The id of the lock currently held, or `undefined` when the app is unlocked. The lock file is not
43
- * encrypted - a lock id identifies a run, and reveals nothing about the state it guards.
44
- */
45
- async getAppLock() {
46
- return FileAppLockUtility.getAppLock(this.lockFilePath);
47
- }
48
- /**
49
- * Reads a state file.
50
- *
51
- * @throws {@link TransactionError} With the message `No state found!` when the file does not exist.
52
- */
53
- async getState(stateFileName) {
54
- try {
55
- return await FileUtility.decryptFileToBuffer(join(this.localStateDirectoryPath, stateFileName + '.enc'), this.encryptionKey);
56
- }
57
- catch (error) {
58
- if (error.code === 'ENOENT') {
59
- throw new TransactionError('No state found!');
60
- }
61
- throw error;
62
- }
63
- }
64
- /**
65
- * Whether `lockId` is the lock currently held.
66
- *
67
- * @throws {@link TransactionError} With the message `Invalid lock ID!` when a different lock is held.
68
- */
69
- async isAppLocked(lockId) {
70
- return FileAppLockUtility.isAppLocked(this.lockFilePath, lockId);
71
- }
72
- /**
73
- * The names of the state files whose name starts with `prefix`, with the `.enc` suffix removed so
74
- * a caller can read them back by the name it knows.
75
- */
76
- async listStates(prefix) {
77
- let entries;
78
- try {
79
- entries = await readdir(this.localStateDirectoryPath);
80
- }
81
- catch (error) {
82
- if (error.code === 'ENOENT') {
83
- return [];
84
- }
85
- throw error;
86
- }
87
- return entries
88
- .filter((entry) => entry.endsWith('.enc') && entry.startsWith(prefix))
89
- .map((entry) => entry.slice(0, -'.enc'.length));
90
- }
91
- /**
92
- * Takes the app lock, writing its id into `local-state.lock` beside the state files.
93
- *
94
- * @throws {@link TransactionError} When a lock is held, naming the id that holds it.
95
- */
96
- async lockApp() {
97
- await FileUtility.ensureDirectory(this.localStateDirectoryPath);
98
- return FileAppLockUtility.lockApp(this.lockFilePath);
99
- }
100
- /**
101
- * Writes a state file, overwriting whatever was there.
102
- */
103
- async saveState(stateFileName, data) {
104
- await FileUtility.ensureDirectory(this.localStateDirectoryPath);
105
- await FileUtility.encryptBufferToFile(data, join(this.localStateDirectoryPath, stateFileName + '.enc'), this.encryptionKey);
106
- }
107
- /**
108
- * Releases the app lock by deleting the lock file.
109
- *
110
- * @throws {@link TransactionError} With the message `Invalid lock ID!` when a different lock is held.
111
- */
112
- async unlockApp(lockId) {
113
- return FileAppLockUtility.unlockApp(this.lockFilePath, lockId);
114
- }
115
- }
116
- //# sourceMappingURL=local-encryption.state-provider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"local-encryption.state-provider.js","sourceRoot":"","sources":["../../../src/services/state-management/local-encryption.state-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAGhE;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,4BAA4B;IAOvC;;;;OAIG;IACH,YAAY,uBAA+B,EAAE,aAAqB;QAChE,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,gBAAgB,CAAC,sCAAsC,CAAC,CAAC;QACrE,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QAEnC,IAAI,CAAC,uBAAuB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;QAChE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE,kBAAkB,CAAC,CAAC;IAC7E,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,aAAqB;QACrC,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE,aAAa,GAAG,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACxF,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,UAAU;QACd,OAAO,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC1D,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,QAAQ,CAAC,aAAqB;QAClC,IAAI,CAAC;YACH,OAAO,MAAM,WAAW,CAAC,mBAAmB,CAC1C,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE,aAAa,GAAG,MAAM,CAAC,EAC1D,IAAI,CAAC,aAAa,CACnB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC5B,MAAM,IAAI,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;YAChD,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,WAAW,CAAC,MAAc;QAC9B,OAAO,kBAAkB,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACnE,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,UAAU,CAAC,MAAc;QAC7B,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC5B,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QAED,OAAO,OAAO;aACX,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;aACrE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACpD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,OAAO;QACX,MAAM,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAChE,OAAO,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACvD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS,CAAC,aAAqB,EAAE,IAAY;QACjD,MAAM,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAChE,MAAM,WAAW,CAAC,mBAAmB,CACnC,IAAI,EACJ,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE,aAAa,GAAG,MAAM,CAAC,EAC1D,IAAI,CAAC,aAAa,CACnB,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,SAAS,CAAC,MAAc;QAC5B,OAAO,kBAAkB,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACjE,CAAC;CACF"}