libmodulor 0.4.0 → 0.5.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 (204) hide show
  1. package/CHANGELOG.md +18 -1
  2. package/README.md +3 -3
  3. package/dist/esm/app/workers/AppSrcFilePathBuilder.d.ts +16 -0
  4. package/dist/esm/app/workers/AppSrcFilePathBuilder.js +6 -4
  5. package/dist/esm/apps/Helper/index.js +1 -0
  6. package/dist/esm/apps/Helper/src/ucds/GenerateAppsTestsUCD.js +3 -2
  7. package/dist/esm/bundlers/vite/StripUCDLifecycleServerPlugin.js +3 -0
  8. package/dist/esm/convention.d.ts +1 -0
  9. package/dist/esm/convention.js +17 -4
  10. package/dist/esm/dt/Validation.d.ts +8 -0
  11. package/dist/esm/dt/Validation.js +8 -0
  12. package/dist/esm/dt/base/TBase.d.ts +2 -1
  13. package/dist/esm/dt/base/TBoolean.js +2 -0
  14. package/dist/esm/dt/base/TInt.js +3 -0
  15. package/dist/esm/dt/base/TNumber.js +2 -0
  16. package/dist/esm/dt/base/TObject.d.ts +15 -0
  17. package/dist/esm/dt/base/TObject.js +14 -0
  18. package/dist/esm/dt/base/TString.js +1 -1
  19. package/dist/esm/dt/final/TAmount.js +1 -0
  20. package/dist/esm/dt/final/TCountryISO3166Alpha2.js +1 -0
  21. package/dist/esm/dt/final/TCurrencyISO4217.js +1 -0
  22. package/dist/esm/dt/final/TDateTimeFormat.js +1 -0
  23. package/dist/esm/dt/final/TEmail.js +2 -0
  24. package/dist/esm/dt/final/TEmoji.js +4 -0
  25. package/dist/esm/dt/final/TFile.js +3 -0
  26. package/dist/esm/dt/final/THostAddress.js +2 -0
  27. package/dist/esm/dt/final/TIPv6.js +1 -0
  28. package/dist/esm/dt/final/TJWT.js +8 -0
  29. package/dist/esm/dt/final/TPercentage.js +5 -0
  30. package/dist/esm/dt/final/TSQLQuery.js +1 -0
  31. package/dist/esm/dt/final/TSSHPrivateKey.js +3 -1
  32. package/dist/esm/dt/final/TSemVerVersion.js +1 -0
  33. package/dist/esm/dt/final/TShellCommand.js +1 -0
  34. package/dist/esm/dt/final/TURL.js +2 -0
  35. package/dist/esm/dt/final/TUUID.js +1 -0
  36. package/dist/esm/dt/final/TYesNo.js +1 -1
  37. package/dist/esm/i18n/WordingManager.d.ts +16 -0
  38. package/dist/esm/i18n/types.d.ts +5 -0
  39. package/dist/esm/icon/Icon.d.ts +7 -0
  40. package/dist/esm/index.d.ts +3 -0
  41. package/dist/esm/index.js +4 -0
  42. package/dist/esm/product/manifest.d.ts +15 -0
  43. package/dist/esm/products/Helper/index.js +3 -0
  44. package/dist/esm/products/Helper/manifest.d.ts +6 -1
  45. package/dist/esm/std/BufferManager.d.ts +18 -0
  46. package/dist/esm/std/ClockManager.d.ts +5 -0
  47. package/dist/esm/std/EnvironmentManager.d.ts +10 -0
  48. package/dist/esm/std/HTTPAPICaller.d.ts +6 -0
  49. package/dist/esm/std/I18nManager.d.ts +26 -0
  50. package/dist/esm/std/JWTManager.d.ts +26 -0
  51. package/dist/esm/std/JobManager.d.ts +6 -0
  52. package/dist/esm/std/LLMManager.d.ts +25 -0
  53. package/dist/esm/std/LLMManager.js +1 -0
  54. package/dist/esm/std/PromptManager.d.ts +8 -0
  55. package/dist/esm/std/SettingsManager.d.ts +19 -0
  56. package/dist/esm/std/SettingsManager.js +9 -0
  57. package/dist/esm/std/impl/ConsoleLogger.js +7 -1
  58. package/dist/esm/std/impl/FakeEmailManager.js +1 -0
  59. package/dist/esm/std/impl/FakeJobManager.js +1 -0
  60. package/dist/esm/std/impl/FetchHTTPAPICallExecutor.d.ts +9 -0
  61. package/dist/esm/std/impl/FetchHTTPAPICallExecutor.js +11 -0
  62. package/dist/esm/std/impl/MistralAILLMManager.d.ts +17 -0
  63. package/dist/esm/std/impl/MistralAILLMManager.js +56 -0
  64. package/dist/esm/std/impl/NodeCryptoManager.js +6 -1
  65. package/dist/esm/std/impl/NodeDeterministicCryptoManager.d.ts +14 -0
  66. package/dist/esm/std/impl/NodeDeterministicCryptoManager.js +17 -3
  67. package/dist/esm/std/impl/NodeFSManager.js +10 -0
  68. package/dist/esm/std/impl/NodeHTTPAPICallExecutorAgentBuilder.js +2 -0
  69. package/dist/esm/std/impl/NodePromptManager.js +3 -0
  70. package/dist/esm/std/impl/OllamaLLMManager.d.ts +20 -0
  71. package/dist/esm/std/impl/OllamaLLMManager.js +56 -0
  72. package/dist/esm/std/impl/OpenAILLMManager.d.ts +17 -0
  73. package/dist/esm/std/impl/OpenAILLMManager.js +51 -0
  74. package/dist/esm/std/impl/SimpleHTTPAPICaller.js +14 -0
  75. package/dist/esm/std/impl/SimpleMapI18nManager.js +4 -2
  76. package/dist/esm/std/impl/StdDateClockManager.js +3 -0
  77. package/dist/esm/std/impl/UCDataStoreExternalResourceManager.js +3 -0
  78. package/dist/esm/std/impl/WebCryptoManager.js +9 -0
  79. package/dist/esm/std/index.d.ts +1 -0
  80. package/dist/esm/std/index.js +1 -0
  81. package/dist/esm/target/lib/cli/renderer.js +3 -0
  82. package/dist/esm/target/lib/client/consts.d.ts +3 -0
  83. package/dist/esm/target/lib/client/consts.js +3 -0
  84. package/dist/esm/target/lib/mcp-server/MCPServerBooter.js +1 -0
  85. package/dist/esm/target/lib/react/UCContainer.js +1 -0
  86. package/dist/esm/target/lib/react/UCPanel.js +4 -0
  87. package/dist/esm/target/lib/react/useUC.d.ts +8 -0
  88. package/dist/esm/target/lib/react/useUC.js +22 -0
  89. package/dist/esm/target/lib/react/useUCOR.d.ts +15 -0
  90. package/dist/esm/target/lib/react/useUCOR.js +45 -0
  91. package/dist/esm/target/lib/rn/input.d.ts +7 -0
  92. package/dist/esm/target/lib/rn/input.js +2 -0
  93. package/dist/esm/target/lib/server/AuthenticationChecker.js +2 -1
  94. package/dist/esm/target/lib/server/BasicAuthenticationChecker.js +1 -0
  95. package/dist/esm/target/lib/server/CSPDirectivesBuilder.js +13 -0
  96. package/dist/esm/target/lib/server/CustomerFacingErrorBuilder.js +3 -0
  97. package/dist/esm/target/lib/server/PrivateApiKeyAuthenticationChecker.js +1 -0
  98. package/dist/esm/target/lib/server/PublicApiKeyChecker.js +1 -1
  99. package/dist/esm/target/lib/server/RequestChecker.js +5 -4
  100. package/dist/esm/target/lib/server/RequestHandler.d.ts +5 -0
  101. package/dist/esm/target/lib/server/RequestLogger.js +5 -0
  102. package/dist/esm/target/lib/server/ServerManager.d.ts +19 -0
  103. package/dist/esm/target/lib/server/consts.d.ts +3 -0
  104. package/dist/esm/target/lib/server/consts.js +3 -0
  105. package/dist/esm/target/lib/web/input.d.ts +21 -0
  106. package/dist/esm/target/lib/web/input.js +4 -0
  107. package/dist/esm/target/node-core-cli/NodeCoreCLIManager.js +2 -2
  108. package/dist/esm/target/node-express-server/NodeExpressServerManager.js +5 -0
  109. package/dist/esm/target/node-express-server/lib/AuthCookieCreator.js +1 -1
  110. package/dist/esm/target/node-express-server/middlewares/AuthenticationCheckerMiddlewareBuilder.js +1 -0
  111. package/dist/esm/target/node-express-server/middlewares/PublicApiKeyCheckerMiddlewareBuilder.js +1 -0
  112. package/dist/esm/target/node-express-server/middlewares/RequestCheckerMiddlewareBuilder.js +1 -0
  113. package/dist/esm/target/node-express-server/middlewares/RequestHandlerMiddlewareBuilder.js +8 -0
  114. package/dist/esm/target/node-express-server/middlewares/RequestLoggerMiddlewareBuilder.js +1 -0
  115. package/dist/esm/target/node-mcp-server/NodeLocalStdioMCPServerManager.d.ts +10 -0
  116. package/dist/esm/target/node-mcp-server/NodeLocalStdioMCPServerManager.js +14 -0
  117. package/dist/esm/target/react-native-pure/UCFormFieldControl.js +1 -0
  118. package/dist/esm/testing/AppTester.d.ts +4 -0
  119. package/dist/esm/testing/AppTester.js +16 -0
  120. package/dist/esm/testing/AppTesterConfigurator.d.ts +68 -0
  121. package/dist/esm/testing/UCDataStoreTester.d.ts +9 -0
  122. package/dist/esm/testing/UCDataStoreTester.js +13 -0
  123. package/dist/esm/testing/impl/SimpleAppDocsEmitter.js +22 -2
  124. package/dist/esm/testing/impl/SimpleAppTesterConfigurator.js +1 -0
  125. package/dist/esm/testing/impl/SimpleHTMLAppTestReportEmitter.js +9 -3
  126. package/dist/esm/testing/impl/TypeScriptLibUCDefASTParser.js +12 -4
  127. package/dist/esm/testing/impl/VitestAppTestSuiteEmitter.js +6 -0
  128. package/dist/esm/testing/opts.d.ts +38 -0
  129. package/dist/esm/testing/opts.js +1 -1
  130. package/dist/esm/testing/uc-input.js +2 -0
  131. package/dist/esm/testing/workers/AppTesterCtxInitializer.js +7 -0
  132. package/dist/esm/testing/workers/UCExecutor.js +1 -0
  133. package/dist/esm/testing/workers/checkers/AppIndexChecker.js +1 -0
  134. package/dist/esm/testing/workers/checkers/UCDefSourcesChecker.js +4 -0
  135. package/dist/esm/uc/UC.js +19 -1
  136. package/dist/esm/uc/UCInputField.d.ts +28 -0
  137. package/dist/esm/uc/UCInputField.js +42 -0
  138. package/dist/esm/uc/data.d.ts +3 -0
  139. package/dist/esm/uc/def.d.ts +7 -0
  140. package/dist/esm/uc/exec.d.ts +39 -0
  141. package/dist/esm/uc/exec.js +29 -0
  142. package/dist/esm/uc/ext.d.ts +30 -1
  143. package/dist/esm/uc/helpers/UCOutputBuilder.js +5 -0
  144. package/dist/esm/uc/helpers/UCOutputReader.js +3 -1
  145. package/dist/esm/uc/impl/HTTPUCTransporter.js +4 -0
  146. package/dist/esm/uc/impl/InMemoryUCDataStore.js +7 -0
  147. package/dist/esm/uc/impl/KnexUCDataStore.d.ts +4 -0
  148. package/dist/esm/uc/impl/KnexUCDataStore.js +14 -0
  149. package/dist/esm/uc/impl/SimpleUCManager.js +6 -0
  150. package/dist/esm/uc/input-field.d.ts +60 -0
  151. package/dist/esm/uc/input-field.js +33 -0
  152. package/dist/esm/uc/input.d.ts +24 -0
  153. package/dist/esm/uc/lifecycle/client/IdleClientMain.js +1 -0
  154. package/dist/esm/uc/lifecycle/server/IdleServerMain.js +2 -0
  155. package/dist/esm/uc/manager.d.ts +11 -0
  156. package/dist/esm/uc/metadata.d.ts +10 -0
  157. package/dist/esm/uc/opi-layout.d.ts +3 -0
  158. package/dist/esm/uc/opi.d.ts +8 -0
  159. package/dist/esm/uc/output-field.d.ts +9 -0
  160. package/dist/esm/uc/output-part.d.ts +22 -0
  161. package/dist/esm/uc/output.d.ts +3 -0
  162. package/dist/esm/uc/policies/RoleRegularUCPolicy.js +1 -0
  163. package/dist/esm/uc/policies/funcs.js +1 -0
  164. package/dist/esm/uc/policy.d.ts +22 -0
  165. package/dist/esm/uc/sec.d.ts +9 -0
  166. package/dist/esm/uc/server.d.ts +10 -0
  167. package/dist/esm/uc/settings.d.ts +25 -0
  168. package/dist/esm/uc/side-effect.d.ts +16 -0
  169. package/dist/esm/uc/side-effect.js +16 -0
  170. package/dist/esm/uc/utils/rInput.d.ts +12 -0
  171. package/dist/esm/uc/utils/rInput.js +2 -0
  172. package/dist/esm/uc/utils/rVal.d.ts +25 -0
  173. package/dist/esm/uc/utils/rVal.js +27 -0
  174. package/dist/esm/uc/utils/recIs.d.ts +9 -0
  175. package/dist/esm/uc/utils/recIs.js +12 -1
  176. package/dist/esm/uc/utils/stripUCDLifecycleServer.d.ts +13 -0
  177. package/dist/esm/uc/utils/stripUCDLifecycleServer.js +17 -0
  178. package/dist/esm/uc/utils/ucifcoIsForArray.d.ts +6 -0
  179. package/dist/esm/uc/utils/ucifcoIsForArray.js +6 -0
  180. package/dist/esm/uc/workers/SimpleAggregateFinder.d.ts +12 -0
  181. package/dist/esm/uc/workers/SimpleAggregateFinder.js +12 -0
  182. package/dist/esm/uc/workers/UCBuilder.d.ts +7 -0
  183. package/dist/esm/uc/workers/UCBuilder.js +7 -0
  184. package/dist/esm/uc/workers/UCExecChecker.js +2 -0
  185. package/dist/esm/uc/workers/UCInputFilesProcessor.js +10 -4
  186. package/dist/esm/uc/workers/UCOutputFilesProcessor.js +6 -2
  187. package/dist/esm/utils/async/sleep.d.ts +10 -0
  188. package/dist/esm/utils/async/sleep.js +10 -0
  189. package/dist/esm/utils/http/appendData.js +5 -1
  190. package/dist/esm/utils/ioc/ContainerPrinter.js +2 -0
  191. package/dist/esm/utils/ioc/bindCommon.js +4 -0
  192. package/dist/esm/utils/ioc/bindNodeCLI.js +2 -0
  193. package/dist/esm/utils/ioc/bindNodeCore.js +1 -0
  194. package/dist/esm/utils/ioc/bindProduct.js +2 -0
  195. package/dist/esm/utils/ioc/bindRN.js +1 -0
  196. package/dist/esm/utils/ioc/bindServer.js +1 -0
  197. package/dist/esm/utils/ioc/bindWeb.js +2 -0
  198. package/dist/esm/utils/ioc/container.js +6 -0
  199. package/dist/esm/utils/numbers/units.js +3 -0
  200. package/dist/esm/utils/types/funcs.d.ts +35 -0
  201. package/dist/esm/utils/types/funcs.js +35 -0
  202. package/dist/esm/utils/types/utility-types.d.ts +17 -0
  203. package/dist/esm/utils/types/utility-types.js +1 -0
  204. package/package.json +9 -9
@@ -6,7 +6,17 @@ import type { UCMain } from './main.js';
6
6
  import type { UCOPIBase } from './opi.js';
7
7
  import type { UCPolicy } from './policy.js';
8
8
  export interface UCServerDef<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> {
9
+ /**
10
+ * Define how the use case can be executed
11
+ *
12
+ * When set to {@link UCExecMode.AUTO}, the use case is not mounted on the target (i.e. no endpoint on a server).
13
+ *
14
+ * @defaultValue {@link UCExecMode.USER}
15
+ */
9
16
  execMode?: UCExecMode;
17
+ /**
18
+ * Routine to run when mounting the use case in a {@link ServerManager}
19
+ */
10
20
  init?: Class<UCInit>;
11
21
  main: Class<UCMain<I, OPI0, OPI1>>;
12
22
  policy: Class<UCPolicy<I, OPI0, OPI1>>;
@@ -4,8 +4,33 @@ import type { UCDataStoreDatasetName } from './data-store.js';
4
4
  import type { UCFileInputFieldRefPrefix } from './file.js';
5
5
  import type { UCName } from './metadata.js';
6
6
  export interface UCSettings extends Settings {
7
+ /**
8
+ * The name of the collection/table storing the persisted use cases in the data store
9
+ *
10
+ * @default UC_DEFAULT_SETTINGS.uc_data_store_ucs_dataset_name
11
+ */
7
12
  uc_data_store_ucs_dataset_name: UCDataStoreDatasetName;
13
+ /**
14
+ * The list of disabled use cases (see {@link UCExecChecker})
15
+ *
16
+ * This should be used only in specific cases (e.g. disabling in emergency a use case in production).
17
+ *
18
+ * If you want a feature-flag like mechanism, chances are you need a dedicated setting, "wrapping" multiple use cases.
19
+ *
20
+ * @default UC_DEFAULT_SETTINGS.uc_disabled_use_cases
21
+ */
8
22
  uc_disabled_use_cases: UCName[];
23
+ /**
24
+ * The prefix of the file path when the use case has been processed, before storing
25
+ * @default UC_DEFAULT_SETTINGS.uc_file_ref_prefix
26
+ */
9
27
  uc_file_ref_prefix: UCFileInputFieldRefPrefix;
28
+ /**
29
+ * The directory path where the use case input files are copied after being processed
30
+ *
31
+ * In the future, we can imagine storing in other types of storage (e.g. S3-like).
32
+ *
33
+ * @default UC_DEFAULT_SETTINGS.uc_files_directory_path
34
+ */
10
35
  uc_files_directory_path: FilePath;
11
36
  }
@@ -1,6 +1,22 @@
1
1
  export declare enum UCOutputSideEffectType {
2
+ /**
3
+ * Trigger a clearing of the auth on the calling system (e.g. `SignOut`).
4
+ */
2
5
  CLEAR_AUTH = "CLEAR_AUTH",
6
+ /**
7
+ * Trigger a redirect on the calling system (e.g. after the final round of an OAuth1 flow)
8
+ *
9
+ * NOTE : This is a "final" side effects, which means it must be the last one in the array of side effects.
10
+ * Indeed, in most servers, once you redirect, you cannot do more with the `req`/`res` (e.g. on `express`).
11
+ *
12
+ * It expects a field `redirect: URL` in `output.parts._0.items[0]`.
13
+ */
3
14
  REDIRECT = "REDIRECT",
15
+ /**
16
+ * Trigger a setting of the auth on the calling system (e.g. `SignIn` / `SignUp`).
17
+ *
18
+ * It expects a field `jwt: JWT` in `output.parts._0.items[0]`.
19
+ */
4
20
  SET_AUTH = "SET_AUTH"
5
21
  }
6
22
  export type UCOutputSideEffect = {
@@ -1,6 +1,22 @@
1
1
  export var UCOutputSideEffectType;
2
2
  (function (UCOutputSideEffectType) {
3
+ /**
4
+ * Trigger a clearing of the auth on the calling system (e.g. `SignOut`).
5
+ */
3
6
  UCOutputSideEffectType["CLEAR_AUTH"] = "CLEAR_AUTH";
7
+ /**
8
+ * Trigger a redirect on the calling system (e.g. after the final round of an OAuth1 flow)
9
+ *
10
+ * NOTE : This is a "final" side effects, which means it must be the last one in the array of side effects.
11
+ * Indeed, in most servers, once you redirect, you cannot do more with the `req`/`res` (e.g. on `express`).
12
+ *
13
+ * It expects a field `redirect: URL` in `output.parts._0.items[0]`.
14
+ */
4
15
  UCOutputSideEffectType["REDIRECT"] = "REDIRECT";
16
+ /**
17
+ * Trigger a setting of the auth on the calling system (e.g. `SignIn` / `SignUp`).
18
+ *
19
+ * It expects a field `jwt: JWT` in `output.parts._0.items[0]`.
20
+ */
5
21
  UCOutputSideEffectType["SET_AUTH"] = "SET_AUTH";
6
22
  })(UCOutputSideEffectType || (UCOutputSideEffectType = {}));
@@ -2,9 +2,21 @@ import type { UC } from '../UC.js';
2
2
  import type { UCInput } from '../input.js';
3
3
  import type { UCOPIBase } from '../opi.js';
4
4
  interface Opts {
5
+ /**
6
+ * @defaultValue false
7
+ */
5
8
  forceArrayAsEmpty?: boolean | undefined;
9
+ /**
10
+ * @defaultValue true
11
+ */
6
12
  forceBooleanAsFalse?: boolean | undefined;
13
+ /**
14
+ * @defaultValue false
15
+ */
7
16
  ignoreTransient?: boolean | undefined;
17
+ /**
18
+ * @defaultValue false
19
+ */
8
20
  ignoreUndefined?: boolean | undefined;
9
21
  }
10
22
  export declare function rInput<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>, opts?: Opts): NonNullable<I>;
@@ -32,6 +32,8 @@ export function rInput(uc, opts) {
32
32
  value = [];
33
33
  }
34
34
  if (!ignoreUndefined || (ignoreUndefined && value !== undefined)) {
35
+ // Useful when we get the input before persisting for example.
36
+ // Otherwise it will persist `undefined` as a string in the database, for nothing.
35
37
  input[f.key] = value;
36
38
  }
37
39
  }
@@ -1,5 +1,30 @@
1
1
  import type { DataType } from '../../dt/index.js';
2
2
  import type { Value } from '../value.js';
3
+ /**
4
+ * Read the value as a primitive
5
+ *
6
+ * To be used when the field has a 0..1 cardinality.
7
+ *
8
+ * @param value
9
+ * @param or
10
+ * @returns
11
+ */
3
12
  export declare function rVal0<T extends DataType>(value: Value<T>, or?: T): T | null;
13
+ /**
14
+ * Require the value as a primitive
15
+ *
16
+ * To be used when the field has a 1..1 cardinality.
17
+ *
18
+ * @param value
19
+ * @returns
20
+ */
4
21
  export declare function reqVal0<T extends DataType>(value: Value<T>): T;
22
+ /**
23
+ * Get the value as an array
24
+ *
25
+ * To be used when the field has a 0..* cardinality.
26
+ *
27
+ * @param value
28
+ * @returns
29
+ */
5
30
  export declare function rValArr<T extends DataType>(value: Value<T>): T[];
@@ -1,10 +1,29 @@
1
1
  import { isBlank } from '../../utils/index.js';
2
+ // NOTE : the "r" prefix stands for "read" and the "req" prefix stands for "require"
3
+ /**
4
+ * Read the value as a primitive
5
+ *
6
+ * To be used when the field has a 0..1 cardinality.
7
+ *
8
+ * @param value
9
+ * @param or
10
+ * @returns
11
+ */
12
+ // TODO : Find a way to return `T` when `or` is set (function override does not work)
2
13
  export function rVal0(value, or) {
3
14
  if (isBlank(value)) {
4
15
  return or ?? null;
5
16
  }
6
17
  return Array.isArray(value) ? (value[0] ?? null) : value;
7
18
  }
19
+ /**
20
+ * Require the value as a primitive
21
+ *
22
+ * To be used when the field has a 1..1 cardinality.
23
+ *
24
+ * @param value
25
+ * @returns
26
+ */
8
27
  export function reqVal0(value) {
9
28
  const val = rVal0(value);
10
29
  if (isBlank(val)) {
@@ -12,6 +31,14 @@ export function reqVal0(value) {
12
31
  }
13
32
  return val;
14
33
  }
34
+ /**
35
+ * Get the value as an array
36
+ *
37
+ * To be used when the field has a 0..* cardinality.
38
+ *
39
+ * @param value
40
+ * @returns
41
+ */
15
42
  export function rValArr(value) {
16
43
  if (isBlank(value)) {
17
44
  return [];
@@ -2,4 +2,13 @@ import type { UCDataStoreRecord } from '../data-store.js';
2
2
  import type { UCData } from '../data.js';
3
3
  import type { UCInput } from '../input.js';
4
4
  import type { UCName } from '../metadata.js';
5
+ /**
6
+ * Check whether a data store records corresponds to the passed type
7
+ *
8
+ * Useful when fetching multiple records at once and looping over them to build an aggregate
9
+ *
10
+ * @param rec
11
+ * @param name
12
+ * @returns
13
+ */
5
14
  export declare const recIs: <I extends UCInput | undefined = undefined, D extends UCData | null = null>(rec: UCDataStoreRecord<any, any>, name: UCName) => rec is UCDataStoreRecord<I, D>;
@@ -1 +1,12 @@
1
- export const recIs = (rec, name) => rec.name === name;
1
+ /**
2
+ * Check whether a data store records corresponds to the passed type
3
+ *
4
+ * Useful when fetching multiple records at once and looping over them to build an aggregate
5
+ *
6
+ * @param rec
7
+ * @param name
8
+ * @returns
9
+ */
10
+ export const recIs = (
11
+ // biome-ignore lint/suspicious/noExplicitAny: can be anything
12
+ rec, name) => rec.name === name;
@@ -1,2 +1,15 @@
1
1
  import type { UCDefSourceRaw } from '../def.js';
2
+ /**
3
+ * Strip the server part of the UCD
4
+ *
5
+ * To be used by bundlers when building for the web for example, or any other clients (e.g. React Native).
6
+ *
7
+ * WARNING : This implementation is very naive and will have unexpected behaviors when the UCD has a specific shape.
8
+ * For instance, if there is another `server: {` occurence than the lifecycle.server definition, it will be wrongly replaced.
9
+ *
10
+ * TODO : Make this implementation more robust (let's try not to use an AST parser though, to keep things fast and simple).
11
+ *
12
+ * @param source
13
+ * @returns
14
+ */
2
15
  export declare function stripUCDLifecycleServer(source: UCDefSourceRaw): UCDefSourceRaw;
@@ -5,6 +5,19 @@ const TOKEN_IMPORT_END = ';';
5
5
  const TOKEN_LIFECYCLE_SERVER = 'server: {';
6
6
  const TOKEN_LIFECYCLE_SERVER_END = '},';
7
7
  const TOKEN_LIFECYCLE_SERVER_REPLACE = 'server: true,';
8
+ /**
9
+ * Strip the server part of the UCD
10
+ *
11
+ * To be used by bundlers when building for the web for example, or any other clients (e.g. React Native).
12
+ *
13
+ * WARNING : This implementation is very naive and will have unexpected behaviors when the UCD has a specific shape.
14
+ * For instance, if there is another `server: {` occurence than the lifecycle.server definition, it will be wrongly replaced.
15
+ *
16
+ * TODO : Make this implementation more robust (let's try not to use an AST parser though, to keep things fast and simple).
17
+ *
18
+ * @param source
19
+ * @returns
20
+ */
8
21
  export function stripUCDLifecycleServer(source) {
9
22
  const occurrences = [
10
23
  ...source.matchAll(new RegExp(UC_MAIN_SERVER_SUFFIX, 'g')),
@@ -14,6 +27,7 @@ export function stripUCDLifecycleServer(source) {
14
27
  let occIdx = 0;
15
28
  for (const occ of occurrences) {
16
29
  if (count === 3 && occIdx === 1) {
30
+ // Skip the 2nd occurrence as it is part of the import of the 1st (Rrrrh very hacky...)
17
31
  occIdx += 1;
18
32
  continue;
19
33
  }
@@ -37,6 +51,9 @@ export function stripUCDLifecycleServer(source) {
37
51
  toReplace.push(toRep);
38
52
  occIdx += 1;
39
53
  }
54
+ // Flip the items to replace in order to remove the usage before the imports
55
+ // This is related to the edge case of IdleServerMain that we remove from the imports list,
56
+ // while for specific ServerMain, we remove the entire import instruction.
40
57
  toReplace.reverse();
41
58
  let cleaned = source;
42
59
  for (const { str } of toReplace) {
@@ -1,2 +1,8 @@
1
1
  import { UCInputFieldChangeOperator } from '../input-field.js';
2
+ /**
3
+ * Check whether a {@link UCInputFieldChangeOperator} is for an array or not.
4
+ *
5
+ * @param op
6
+ * @returns
7
+ */
2
8
  export declare function ucifcoIsForArray(op: UCInputFieldChangeOperator): op is UCInputFieldChangeOperator.ADD | UCInputFieldChangeOperator.REMOVE;
@@ -1,4 +1,10 @@
1
1
  import { UCInputFieldChangeOperator } from '../input-field.js';
2
+ /**
3
+ * Check whether a {@link UCInputFieldChangeOperator} is for an array or not.
4
+ *
5
+ * @param op
6
+ * @returns
7
+ */
2
8
  export function ucifcoIsForArray(op) {
3
9
  return [
4
10
  UCInputFieldChangeOperator.ADD,
@@ -12,6 +12,18 @@ interface Input {
12
12
  interface Output<I extends UCInput | undefined = undefined, D extends UCData | null = null> {
13
13
  record: UCDataStoreRecord<I, D>;
14
14
  }
15
+ /**
16
+ * Find an aggregate by id by replaying additive use cases and removal ones
17
+ *
18
+ * This works only in simple scenarios where you have the following use cases :
19
+ * - `CreateX`
20
+ * - `CreateX`, `DeleteX`
21
+ * - `CreateX`, `[DeleteX, ArchiveX]`
22
+ *
23
+ * If there is an `UpdateX` for example, do not use this as the record won't be accurate. Replay the records yourself with {@link UCDataStore.read()}.
24
+ *
25
+ * It throws a {@link NotFoundError} if there are more than one record (in which case somethin is wrong with the data store) or none.
26
+ */
15
27
  export declare class SimpleAggregateFinder implements Worker<Input, Promise<Output>> {
16
28
  private ucDataStore;
17
29
  constructor(ucDataStore: UCDataStore);
@@ -12,6 +12,18 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
12
  };
13
13
  import { inject, injectable } from 'inversify';
14
14
  import { NotFoundError } from '../../error/index.js';
15
+ /**
16
+ * Find an aggregate by id by replaying additive use cases and removal ones
17
+ *
18
+ * This works only in simple scenarios where you have the following use cases :
19
+ * - `CreateX`
20
+ * - `CreateX`, `DeleteX`
21
+ * - `CreateX`, `[DeleteX, ArchiveX]`
22
+ *
23
+ * If there is an `UpdateX` for example, do not use this as the record won't be accurate. Replay the records yourself with {@link UCDataStore.read()}.
24
+ *
25
+ * It throws a {@link NotFoundError} if there are more than one record (in which case somethin is wrong with the data store) or none.
26
+ */
15
27
  let SimpleAggregateFinder = class SimpleAggregateFinder {
16
28
  ucDataStore;
17
29
  constructor(ucDataStore) {
@@ -4,6 +4,13 @@ import type { UCInput } from '../input.js';
4
4
  import type { UCOPIBase } from '../opi.js';
5
5
  type Input<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> = ArgsRecord<I, OPI0, OPI1>;
6
6
  type Output<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> = UC<I, OPI0, OPI1>;
7
+ /**
8
+ * Build a Use Case
9
+ *
10
+ * When initially implemented this, {@link I18nManager} was injected to provide the `languageCode` to the {@link UC}.
11
+ *
12
+ * But this dependency has been removed when introducing {@link WordingManager}. Let's keep it for now in case we need to inject something.
13
+ */
7
14
  export declare class UCBuilder implements Worker<Input, Output> {
8
15
  exec<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>({ appManifest, auth, def }: Input<I, OPI0, OPI1>): Output<I, OPI0, OPI1>;
9
16
  }
@@ -6,6 +6,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  import { injectable } from 'inversify';
8
8
  import { UC } from '../UC.js';
9
+ /**
10
+ * Build a Use Case
11
+ *
12
+ * When initially implemented this, {@link I18nManager} was injected to provide the `languageCode` to the {@link UC}.
13
+ *
14
+ * But this dependency has been removed when introducing {@link WordingManager}. Let's keep it for now in case we need to inject something.
15
+ */
9
16
  let UCBuilder = class UCBuilder {
10
17
  exec({ appManifest, auth, def }) {
11
18
  return new UC(appManifest, def, auth);
@@ -54,6 +54,8 @@ let UCExecChecker = class UCExecChecker {
54
54
  break;
55
55
  }
56
56
  case 'server':
57
+ // Nothing specific for the moment as everything is checked in function of authentication
58
+ // @see AuthenticationChecker called in the request lifecycle
57
59
  output.allowed = typeof server === 'object';
58
60
  break;
59
61
  default:
@@ -42,6 +42,9 @@ let UCInputFilesProcessor = class UCInputFilesProcessor {
42
42
  if (isRepeatable) {
43
43
  const files = rValArr(field.getValue());
44
44
  const fileNameRefs = await Promise.all(files.map(async (f) => this.processFile(f)));
45
+ // Although the field is a file, here we fill it with the refs (for persistence)
46
+ // TODO : Improve the mgmt of FileNameRef vs actual File at the use case level
47
+ // I think we need to introduce another value, something like `setValueSerialized` or similar.
45
48
  field.setValue(UCInputFieldChangeOperator.SET, fileNameRefs);
46
49
  }
47
50
  else {
@@ -54,12 +57,15 @@ let UCInputFilesProcessor = class UCInputFilesProcessor {
54
57
  }
55
58
  }
56
59
  async processFile(file) {
57
- const extension = this.fsManager.fileExtension(file.name);
60
+ const extension = this.fsManager.fileExtension(file.name); // => jpg
58
61
  const prefix = this.clockManager.nowToKey();
59
- const fileName = `${prefix}-${this.cryptoManager.randomUUID()}.${extension}`;
60
- const fileNameRef = `${this.s().uc_file_ref_prefix}${fileName}`;
62
+ const fileName = `${prefix}-${this.cryptoManager.randomUUID()}.${extension}`; // => 20230110143732-155eb8d3-9af5-430e-b856-248007859df1.jpg
63
+ const fileNameRef = `${this.s().uc_file_ref_prefix}${fileName}`; // => $ref:20230110143732-155eb8d3-9af5-430e-b856-248007859df1.jpg
64
+ // When calling this client side, we still have a https://developer.mozilla.org/en-US/docs/Web/API/File
65
+ // Consider moving this logic to UCManager.execClient ?
66
+ // TODO : Improve client/server input files management
61
67
  const path = file instanceof File ? file.name : file.path;
62
- await this.fsManager.cp(path, this.fsManager.path(this.s().uc_files_directory_path, fileName));
68
+ await this.fsManager.cp(path, this.fsManager.path(this.s().uc_files_directory_path, fileName)); // => /path/to/files/20230110143732-155eb8d3-9af5-430e-b856-248007859df1.jpg
63
69
  await this.fsManager.rm(path);
64
70
  return fileNameRef;
65
71
  }
@@ -36,8 +36,12 @@ let UCOutputFilesProcessor = class UCOutputFilesProcessor {
36
36
  output.filePaths = await Promise.all(fileNameRefs.map(async (fileNameRef) => {
37
37
  let filePath;
38
38
  if (typeof fileNameRef === 'string') {
39
- const fileName = fileNameRef.replace(this.s().uc_file_ref_prefix, '');
40
- filePath = this.fsManager.path(this.s().uc_files_directory_path, fileName);
39
+ // If they have been processed by UCInputFilesProcessor, the refs are not actual File.
40
+ // They are string like '$ref:20230110143732-155eb8d3-9af5-430e-b856-248007859df1.jpg'.
41
+ // Hence this workaround.
42
+ // TODO : Find a better way to process output files
43
+ const fileName = fileNameRef.replace(this.s().uc_file_ref_prefix, ''); // => 20230110143732-155eb8d3-9af5-430e-b856-248007859df1.jpg
44
+ filePath = this.fsManager.path(this.s().uc_files_directory_path, fileName); // => /path/to/files/20230110143732-155eb8d3-9af5-430e-b856-248007859df1.jpg
41
45
  }
42
46
  else {
43
47
  filePath = fileNameRef.path;
@@ -1,2 +1,12 @@
1
1
  import type { UIntDuration } from '../../dt/index.js';
2
+ /**
3
+ * Sleep during the specified duration
4
+ *
5
+ * NOTE : We are in an async world so do this only when necessary or when you want to "fake" time.
6
+ * Generally speaking, if something is fast, do not make it slower just for the sake of showing a fancy animation.
7
+ * Well... If it's a good one, maybe.
8
+ *
9
+ * @param durationInMs
10
+ * @returns
11
+ */
2
12
  export declare function sleep(durationInMs: UIntDuration): Promise<void>;
@@ -1,3 +1,13 @@
1
+ /**
2
+ * Sleep during the specified duration
3
+ *
4
+ * NOTE : We are in an async world so do this only when necessary or when you want to "fake" time.
5
+ * Generally speaking, if something is fast, do not make it slower just for the sake of showing a fancy animation.
6
+ * Well... If it's a good one, maybe.
7
+ *
8
+ * @param durationInMs
9
+ * @returns
10
+ */
1
11
  export function sleep(durationInMs) {
2
12
  return new Promise((resolve) => {
3
13
  setTimeout(() => {
@@ -1,4 +1,8 @@
1
- export async function appendData(data, func) {
1
+ export async function appendData(data,
2
+ // biome-ignore lint/suspicious/noExplicitAny: can be anything
3
+ func) {
4
+ // Checking undefined and null because Object.keys(undefined|null) throws
5
+ // TypeError: Cannot convert undefined or null to object
2
6
  if (data === undefined || data === null) {
3
7
  return;
4
8
  }
@@ -18,6 +18,8 @@ let ContainerPrinter = class ContainerPrinter {
18
18
  this.logger = logger;
19
19
  }
20
20
  async exec({ container }) {
21
+ // See https://github.com/inversify/InversifyJS/issues/1584
22
+ // @ts-ignore
21
23
  const dictionary = container._bindingDictionary._map;
22
24
  const entries = [];
23
25
  const keys = [...dictionary.keys()].map(this.symToString);
@@ -1,3 +1,4 @@
1
+ // NOTE : Expose this only at a higher level, otherwise, if exposed in utils/index.js, it will create circular dependencies
1
2
  import { APP_NAME_PLACEHOLDER, PRODUCT_NAME_PLACEHOLDER, } from '../../convention.js';
2
3
  import { ConsoleLogger } from '../../std/impl/ConsoleLogger.js';
3
4
  import { FetchHTTPAPICallExecutor } from '../../std/impl/FetchHTTPAPICallExecutor.js';
@@ -25,12 +26,14 @@ export function bindCommon(container, settingsFunc) {
25
26
  ...commonSettings,
26
27
  ...settingsFunc?.(commonSettings),
27
28
  };
29
+ // product
28
30
  if (!container.isBound('ProductManifest')) {
29
31
  container.bind('ProductManifest').toConstantValue({
30
32
  appReg: [{ name: APP_NAME_PLACEHOLDER }],
31
33
  name: PRODUCT_NAME_PLACEHOLDER,
32
34
  });
33
35
  }
36
+ // std
34
37
  container.bind('ClockManager').to(StdDateClockManager);
35
38
  container
36
39
  .bind('FormDataBuilder')
@@ -56,6 +59,7 @@ export function bindCommon(container, settingsFunc) {
56
59
  .bind('ServerClientManager')
57
60
  .to(SettingsServerClientManager);
58
61
  container.bind('XMLManager').to(NoopXMLManager);
62
+ // uc
59
63
  bindProvider(container, 'UCInit');
60
64
  bindProvider(container, 'UCMain');
61
65
  bindProvider(container, 'UCPolicy');
@@ -1,7 +1,9 @@
1
1
  import { NodePromptManager } from '../../std/impl/NodePromptManager.js';
2
2
  import { PromptUCClientConfirmManager } from '../../uc/impl/PromptUCClientConfirmManager.js';
3
3
  export function bindNodeCLI(container) {
4
+ // std
4
5
  container.bind('PromptManager').to(NodePromptManager);
6
+ // uc
5
7
  container
6
8
  .rebind('UCClientConfirmManager')
7
9
  .to(PromptUCClientConfirmManager);
@@ -4,6 +4,7 @@ import { NodeEnvironmentManager } from '../../std/impl/NodeEnvironmentManager.js
4
4
  import { NodeFSManager } from '../../std/impl/NodeFSManager.js';
5
5
  import { NodeFormDataBuilder } from '../../std/impl/NodeFormDataBuilder.js';
6
6
  export function bindNodeCore(container) {
7
+ // std
7
8
  container.bind('BufferManager').to(NodeBufferManager);
8
9
  container.bind('CryptoManager').to(NodeCryptoManager);
9
10
  container
@@ -1,4 +1,6 @@
1
1
  export function bindProduct(container, productManifest, productI18n) {
2
+ // Using rebind because these are already bound by default in {@link bindCommon}.
3
+ // The goal is to make it easier to get started for a user.
2
4
  container.rebind('I18n').toConstantValue(productI18n);
3
5
  container
4
6
  .rebind('ProductManifest')
@@ -1,4 +1,5 @@
1
1
  import { BufferLibBufferManager } from '../../std/impl/BufferLibBufferManager.js';
2
2
  export function bindRN(container) {
3
+ // std
3
4
  container.bind('BufferManager').to(BufferLibBufferManager);
4
5
  }
@@ -2,6 +2,7 @@ import { JoseJWTManager } from '../../index.std-jwt-manager-jose.js';
2
2
  import { FakeEmailManager } from '../../std/impl/FakeEmailManager.js';
3
3
  import { FakeJobManager } from '../../std/impl/FakeJobManager.js';
4
4
  export function bindServer(container) {
5
+ // std
5
6
  container.bind('EmailManager').to(FakeEmailManager);
6
7
  container.bind('JWTManager').to(JoseJWTManager);
7
8
  container.bind('JobManager').to(FakeJobManager);
@@ -3,9 +3,11 @@ import { WebCryptoManager } from '../../std/impl/WebCryptoManager.js';
3
3
  import { WebFSManager } from '../../std/impl/WebFSManager.js';
4
4
  import { WebUCClientConfirmManager } from '../../uc/impl/WebUCClientConfirmManager.js';
5
5
  export function bindWeb(container) {
6
+ // std
6
7
  container.bind('BufferManager').to(BufferLibBufferManager);
7
8
  container.bind('CryptoManager').to(WebCryptoManager);
8
9
  container.bind('FSManager').to(WebFSManager);
10
+ // uc
9
11
  container
10
12
  .rebind('UCClientConfirmManager')
11
13
  .to(WebUCClientConfirmManager);
@@ -1,3 +1,9 @@
1
1
  export const CONTAINER_OPTS = {
2
+ /**
3
+ * Allows us to avoid binding concrete classes
4
+ *
5
+ * @see https://github.com/inversify/InversifyJS/issues/1302
6
+ * @see https://github.com/inversify/InversifyJS/blob/master/wiki/container_api.md#autobindinjectable
7
+ */
2
8
  autoBindInjectable: true,
3
9
  };
@@ -1,3 +1,6 @@
1
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#options
2
+ // https://unicode.org/reports/tr35/tr35-general.html#Unit_Elements
3
+ // https://tc39.es/ecma402/#table-sanctioned-single-unit-identifiers
1
4
  const CORE_UNITS = [
2
5
  'acre',
3
6
  'bit',
@@ -1,6 +1,41 @@
1
1
  import type { NumIndex, UIntQuantity } from '../../dt/index.js';
2
+ /**
3
+ * Assert that the value is defined
4
+ * @param value
5
+ * @param key
6
+ * @see isBlank
7
+ */
2
8
  export declare function assertIsDefined<T>(value: T, key: string): asserts value is NonNullable<T>;
9
+ /**
10
+ * Checker whether the value is blank or not
11
+ *
12
+ * Blank means `undefined`, `null`, `''` (if string), `[]` (if array).
13
+ *
14
+ * This is insipred by Ruby's `blank?` method.
15
+ *
16
+ * @param value
17
+ * @returns
18
+ */
3
19
  export declare function isBlank<T>(value: T | T[] | undefined | null): value is undefined | null;
20
+ /**
21
+ * Get an array filled with `[0 .. n-1]`
22
+ * @param n
23
+ * @returns
24
+ */
4
25
  export declare function range(n: UIntQuantity): NumIndex[];
26
+ /**
27
+ * Get a random item from the array
28
+ *
29
+ * Although the name is inspired by Ruby's, the signature and implementation is not exactly the same (for now).
30
+ *
31
+ * @param items
32
+ * @returns
33
+ */
5
34
  export declare function sample<T>(items: T[]): T | null;
35
+ /**
36
+ * Get an array of size `n` filled with `val`
37
+ * @param val
38
+ * @param n
39
+ * @returns
40
+ */
6
41
  export declare function tupleOf<T>(val: T, n: UIntQuantity): T[];