quidproquo-core 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/lib/commonjs/actions/ai/AiMessage.d.ts +9 -1
  2. package/lib/commonjs/actions/ai/AiPromptActionRequester.d.ts +2 -0
  3. package/lib/commonjs/actions/ai/AiPromptActionRequester.js +1 -0
  4. package/lib/commonjs/actions/ai/AiPromptActionTypes.d.ts +2 -0
  5. package/lib/commonjs/actions/ai/AiPromptStreamActionRequester.d.ts +2 -0
  6. package/lib/commonjs/actions/ai/AiPromptStreamActionRequester.js +1 -0
  7. package/lib/commonjs/actions/ai/AiPromptStreamActionTypes.d.ts +2 -0
  8. package/lib/commonjs/actions/ai/AiReasoningConfig.d.ts +8 -0
  9. package/lib/commonjs/actions/ai/AiReasoningConfig.js +2 -0
  10. package/lib/commonjs/actions/ai/index.d.ts +1 -0
  11. package/lib/commonjs/actions/ai/index.js +1 -0
  12. package/lib/commonjs/actions/date/DateNowActionTypes.d.ts +3 -2
  13. package/lib/commonjs/actions/file/index.d.ts +2 -2
  14. package/lib/commonjs/actions/keyValueStore/KeyValueStoreUpsertActionRequester.d.ts +1 -0
  15. package/lib/commonjs/actions/keyValueStore/KeyValueStoreUpsertActionRequester.js +8 -1
  16. package/lib/commonjs/actions/keyValueStore/KeyValueStoreUpsertActionTypes.d.ts +1 -0
  17. package/lib/commonjs/actions/userDirectory/UserDirectoryActionType.d.ts +2 -1
  18. package/lib/commonjs/config/index.d.ts +1 -1
  19. package/lib/commonjs/config/utils/index.d.ts +2 -2
  20. package/lib/commonjs/index.d.ts +1 -1
  21. package/lib/commonjs/proiseify/getSystemExecuteStoryActionProcessor.js +9 -1
  22. package/lib/commonjs/runtime/resolveStoryWithLogs.js +26 -9
  23. package/lib/commonjs/stories/askRetry.d.ts +5 -1
  24. package/lib/commonjs/stories/askRetry.js +7 -2
  25. package/lib/commonjs/types/QpqIsoDateTime.d.ts +23 -0
  26. package/lib/commonjs/types/QpqIsoDateTime.js +4 -0
  27. package/lib/commonjs/types/index.d.ts +1 -0
  28. package/lib/commonjs/types/index.js +1 -0
  29. package/lib/commonjs/utils/dateTime/getQpqIsoDateTimeFromDate.d.ts +2 -0
  30. package/lib/commonjs/utils/dateTime/getQpqIsoDateTimeFromDate.js +5 -0
  31. package/lib/commonjs/utils/dateTime/getValidQpqIsoDateTime.d.ts +2 -0
  32. package/lib/commonjs/utils/dateTime/getValidQpqIsoDateTime.js +6 -0
  33. package/lib/commonjs/utils/dateTime/index.d.ts +2 -0
  34. package/lib/commonjs/utils/dateTime/index.js +18 -0
  35. package/lib/commonjs/utils/hash/index.d.ts +1 -0
  36. package/lib/commonjs/utils/hash/index.js +1 -0
  37. package/lib/commonjs/utils/hash/sha1.d.ts +12 -0
  38. package/lib/commonjs/utils/hash/sha1.js +85 -0
  39. package/lib/commonjs/utils/index.d.ts +1 -0
  40. package/lib/commonjs/utils/index.js +1 -0
  41. package/lib/commonjs/utils/uuid/generateUuidV5.d.ts +20 -0
  42. package/lib/commonjs/utils/uuid/generateUuidV5.js +54 -0
  43. package/lib/commonjs/utils/uuid/index.d.ts +1 -0
  44. package/lib/commonjs/utils/uuid/index.js +1 -0
  45. package/lib/esm/actions/ai/AiMessage.d.ts +9 -1
  46. package/lib/esm/actions/ai/AiPromptActionRequester.d.ts +2 -0
  47. package/lib/esm/actions/ai/AiPromptActionRequester.js +1 -0
  48. package/lib/esm/actions/ai/AiPromptActionTypes.d.ts +2 -0
  49. package/lib/esm/actions/ai/AiPromptStreamActionRequester.d.ts +2 -0
  50. package/lib/esm/actions/ai/AiPromptStreamActionRequester.js +1 -0
  51. package/lib/esm/actions/ai/AiPromptStreamActionTypes.d.ts +2 -0
  52. package/lib/esm/actions/ai/AiReasoningConfig.d.ts +8 -0
  53. package/lib/esm/actions/ai/AiReasoningConfig.js +1 -0
  54. package/lib/esm/actions/ai/index.d.ts +1 -0
  55. package/lib/esm/actions/ai/index.js +1 -0
  56. package/lib/esm/actions/date/DateNowActionTypes.d.ts +3 -2
  57. package/lib/esm/actions/file/index.d.ts +2 -2
  58. package/lib/esm/actions/file/index.js +2 -2
  59. package/lib/esm/actions/keyValueStore/KeyValueStoreUpsertActionRequester.d.ts +1 -0
  60. package/lib/esm/actions/keyValueStore/KeyValueStoreUpsertActionRequester.js +8 -1
  61. package/lib/esm/actions/keyValueStore/KeyValueStoreUpsertActionTypes.d.ts +1 -0
  62. package/lib/esm/actions/userDirectory/UserDirectoryActionType.d.ts +2 -1
  63. package/lib/esm/config/index.d.ts +1 -1
  64. package/lib/esm/config/index.js +1 -1
  65. package/lib/esm/config/utils/index.d.ts +2 -2
  66. package/lib/esm/config/utils/index.js +2 -2
  67. package/lib/esm/index.d.ts +1 -1
  68. package/lib/esm/index.js +1 -1
  69. package/lib/esm/proiseify/getSystemExecuteStoryActionProcessor.js +9 -1
  70. package/lib/esm/qpqCoreUtilsLib.js +1 -1
  71. package/lib/esm/runtime/resolveStoryWithLogs.js +26 -9
  72. package/lib/esm/stories/askRetry.d.ts +5 -1
  73. package/lib/esm/stories/askRetry.js +8 -3
  74. package/lib/esm/types/QpqIsoDateTime.d.ts +23 -0
  75. package/lib/esm/types/QpqIsoDateTime.js +3 -0
  76. package/lib/esm/types/index.d.ts +1 -0
  77. package/lib/esm/types/index.js +1 -0
  78. package/lib/esm/utils/dateTime/getQpqIsoDateTimeFromDate.d.ts +2 -0
  79. package/lib/esm/utils/dateTime/getQpqIsoDateTimeFromDate.js +1 -0
  80. package/lib/esm/utils/dateTime/getValidQpqIsoDateTime.d.ts +2 -0
  81. package/lib/esm/utils/dateTime/getValidQpqIsoDateTime.js +2 -0
  82. package/lib/esm/utils/dateTime/index.d.ts +2 -0
  83. package/lib/esm/utils/dateTime/index.js +2 -0
  84. package/lib/esm/utils/hash/index.d.ts +1 -0
  85. package/lib/esm/utils/hash/index.js +1 -0
  86. package/lib/esm/utils/hash/sha1.d.ts +12 -0
  87. package/lib/esm/utils/hash/sha1.js +82 -0
  88. package/lib/esm/utils/index.d.ts +1 -0
  89. package/lib/esm/utils/index.js +1 -0
  90. package/lib/esm/utils/uuid/generateUuidV5.d.ts +20 -0
  91. package/lib/esm/utils/uuid/generateUuidV5.js +50 -0
  92. package/lib/esm/utils/uuid/index.d.ts +1 -0
  93. package/lib/esm/utils/uuid/index.js +1 -0
  94. package/package.json +2 -2
@@ -2,12 +2,20 @@ export interface AiTextPart {
2
2
  type: 'text';
3
3
  text: string;
4
4
  }
5
- export interface AiFilePart {
5
+ export interface AiFileUrlPart {
6
6
  type: 'file';
7
7
  url: string;
8
8
  mediaType: string;
9
9
  filename?: string;
10
10
  }
11
+ export interface AiFileDrivePart {
12
+ type: 'file';
13
+ drive: string;
14
+ filepath: string;
15
+ mediaType: string;
16
+ filename?: string;
17
+ }
18
+ export type AiFilePart = AiFileUrlPart | AiFileDrivePart;
11
19
  export interface AiToolCallPart {
12
20
  type: 'tool-call';
13
21
  toolCallId: string;
@@ -1,9 +1,11 @@
1
1
  import { AiMessage } from './AiMessage';
2
2
  import { AiModel } from './AiModel';
3
3
  import { AiPromptActionRequester } from './AiPromptActionTypes';
4
+ import { AiReasoningConfig } from './AiReasoningConfig';
4
5
  export interface AskAiPromptOptions {
5
6
  system?: string;
6
7
  aiName?: string;
7
8
  messages?: AiMessage[];
9
+ reasoning?: AiReasoningConfig;
8
10
  }
9
11
  export declare function askAiPrompt(model: AiModel, prompt: string, options?: AskAiPromptOptions): AiPromptActionRequester;
@@ -11,6 +11,7 @@ function* askAiPrompt(model, prompt, options) {
11
11
  messages: options === null || options === void 0 ? void 0 : options.messages,
12
12
  system: options === null || options === void 0 ? void 0 : options.system,
13
13
  aiName: options === null || options === void 0 ? void 0 : options.aiName,
14
+ reasoning: options === null || options === void 0 ? void 0 : options.reasoning,
14
15
  },
15
16
  };
16
17
  }
@@ -2,12 +2,14 @@ import { Action, ActionProcessor, ActionRequester } from '../../types/Action';
2
2
  import { AiActionType } from './AiActionType';
3
3
  import { AiMessage } from './AiMessage';
4
4
  import { AiModel } from './AiModel';
5
+ import { AiReasoningConfig } from './AiReasoningConfig';
5
6
  export interface AiPromptActionPayload {
6
7
  model: AiModel;
7
8
  prompt: string;
8
9
  messages?: AiMessage[];
9
10
  system?: string;
10
11
  aiName?: string;
12
+ reasoning?: AiReasoningConfig;
11
13
  }
12
14
  export interface AiPromptActionResult {
13
15
  text: string;
@@ -1,9 +1,11 @@
1
1
  import { AiMessage } from './AiMessage';
2
2
  import { AiModel } from './AiModel';
3
3
  import { AiPromptStreamActionRequester } from './AiPromptStreamActionTypes';
4
+ import { AiReasoningConfig } from './AiReasoningConfig';
4
5
  export interface AskAiPromptStreamOptions {
5
6
  system?: string;
6
7
  aiName?: string;
7
8
  messages?: AiMessage[];
9
+ reasoning?: AiReasoningConfig;
8
10
  }
9
11
  export declare function askAiPromptStream(model: AiModel, prompt: string, options?: AskAiPromptStreamOptions): AiPromptStreamActionRequester;
@@ -11,6 +11,7 @@ function* askAiPromptStream(model, prompt, options) {
11
11
  messages: options === null || options === void 0 ? void 0 : options.messages,
12
12
  system: options === null || options === void 0 ? void 0 : options.system,
13
13
  aiName: options === null || options === void 0 ? void 0 : options.aiName,
14
+ reasoning: options === null || options === void 0 ? void 0 : options.reasoning,
14
15
  },
15
16
  };
16
17
  }
@@ -3,6 +3,7 @@ import { StreamHandle } from '../../types/StreamRegistry';
3
3
  import { AiActionType } from './AiActionType';
4
4
  import { AiMessage } from './AiMessage';
5
5
  import { AiModel } from './AiModel';
6
+ import { AiReasoningConfig } from './AiReasoningConfig';
6
7
  import { AiStreamPart } from './types';
7
8
  export interface AiPromptStreamActionPayload {
8
9
  model: AiModel;
@@ -10,6 +11,7 @@ export interface AiPromptStreamActionPayload {
10
11
  messages?: AiMessage[];
11
12
  system?: string;
12
13
  aiName?: string;
14
+ reasoning?: AiReasoningConfig;
13
15
  }
14
16
  export interface AiPromptStreamAction extends Action<AiPromptStreamActionPayload> {
15
17
  type: AiActionType.PromptStream;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Enables extended thinking for a prompt. Presence turns reasoning on; the
3
+ * budget caps how many tokens the model may spend thinking before it answers.
4
+ * Reasoning progress is surfaced as Reasoning* stream parts.
5
+ */
6
+ export interface AiReasoningConfig {
7
+ budgetTokens?: number;
8
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -5,4 +5,5 @@ export * from './AiPromptActionRequester';
5
5
  export * from './AiPromptActionTypes';
6
6
  export * from './AiPromptStreamActionRequester';
7
7
  export * from './AiPromptStreamActionTypes';
8
+ export * from './AiReasoningConfig';
8
9
  export * from './types';
@@ -21,4 +21,5 @@ __exportStar(require("./AiPromptActionRequester"), exports);
21
21
  __exportStar(require("./AiPromptActionTypes"), exports);
22
22
  __exportStar(require("./AiPromptStreamActionRequester"), exports);
23
23
  __exportStar(require("./AiPromptStreamActionTypes"), exports);
24
+ __exportStar(require("./AiReasoningConfig"), exports);
24
25
  __exportStar(require("./types"), exports);
@@ -1,8 +1,9 @@
1
1
  import { Action, ActionProcessor, ActionRequester } from '../../types/Action';
2
+ import { QpqIsoDateTime } from '../../types/QpqIsoDateTime';
2
3
  import { DateActionType } from './DateActionType';
3
4
  export type DateNowActionPayload = undefined;
4
5
  export interface DateNowAction extends Action<DateNowActionPayload> {
5
6
  type: DateActionType.Now;
6
7
  }
7
- export type DateNowActionProcessor = ActionProcessor<DateNowAction, string>;
8
- export type DateNowActionRequester = ActionRequester<DateNowAction, string>;
8
+ export type DateNowActionProcessor = ActionProcessor<DateNowAction, QpqIsoDateTime>;
9
+ export type DateNowActionRequester = ActionRequester<DateNowAction, QpqIsoDateTime>;
@@ -5,8 +5,8 @@ export * from './FileExistsActionRequester';
5
5
  export * from './FileExistsActionTypes';
6
6
  export * from './FileGenerateTemporarySecureUrlActionRequester';
7
7
  export * from './FileGenerateTemporarySecureUrlActionTypes';
8
- export * from "./FileGenerateTemporaryUploadSecureUrlActionRequester";
9
- export * from "./FileGenerateTemporaryUploadSecureUrlActionTypes";
8
+ export * from './FileGenerateTemporaryUploadSecureUrlActionRequester';
9
+ export * from './FileGenerateTemporaryUploadSecureUrlActionTypes';
10
10
  export * from './FileIsColdStorageActionRequester';
11
11
  export * from './FileIsColdStorageActionTypes';
12
12
  export * from './FileListDirectoryActionRequester';
@@ -1,6 +1,7 @@
1
1
  import { KeyValueStoreUpsertActionRequester, KeyValueStoreUpsertOptions } from './KeyValueStoreUpsertActionTypes';
2
2
  export declare const KeyValueStoreUpsertErrorTypeEnum: {
3
3
  ResourceNotFound: string;
4
+ Conflict: string;
4
5
  ServiceUnavailable: string;
5
6
  };
6
7
  export declare function askKeyValueStoreUpsert<KvsItem>(keyValueStoreName: string, item: KvsItem, options?: KeyValueStoreUpsertOptions): KeyValueStoreUpsertActionRequester<KvsItem>;
@@ -4,7 +4,14 @@ exports.KeyValueStoreUpsertErrorTypeEnum = void 0;
4
4
  exports.askKeyValueStoreUpsert = askKeyValueStoreUpsert;
5
5
  const types_1 = require("../../types");
6
6
  const KeyValueStoreActionType_1 = require("./KeyValueStoreActionType");
7
- exports.KeyValueStoreUpsertErrorTypeEnum = (0, types_1.createErrorEnumForAction)(KeyValueStoreActionType_1.KeyValueStoreActionType.Upsert, ['ServiceUnavailable', 'ResourceNotFound']);
7
+ exports.KeyValueStoreUpsertErrorTypeEnum = (0, types_1.createErrorEnumForAction)(KeyValueStoreActionType_1.KeyValueStoreActionType.Upsert, [
8
+ 'ServiceUnavailable',
9
+ 'ResourceNotFound',
10
+ // A conditional (ifNotExists) write lost to an existing item. Namespaced —
11
+ // not ErrorTypeEnum.Conflict — so retry logic can target the write race
12
+ // specifically without also catching domain-level conflicts.
13
+ 'Conflict',
14
+ ]);
8
15
  function* askKeyValueStoreUpsert(keyValueStoreName, item, options) {
9
16
  return yield {
10
17
  type: KeyValueStoreActionType_1.KeyValueStoreActionType.Upsert,
@@ -2,6 +2,7 @@ import { Action, ActionProcessor, ActionRequester } from '../../types/Action';
2
2
  import { KeyValueStoreActionType } from './KeyValueStoreActionType';
3
3
  export interface KeyValueStoreUpsertOptions {
4
4
  ttlInSeconds?: number;
5
+ ifNotExists?: boolean;
5
6
  }
6
7
  export interface KeyValueStoreUpsertActionPayload<KvsItem> {
7
8
  keyValueStoreName: string;
@@ -1,3 +1,4 @@
1
+ import { QpqIsoDateTime } from '../../types/QpqIsoDateTime';
1
2
  import { AuthenticateUserChallenge } from './types';
2
3
  export declare enum UserDirectoryActionType {
3
4
  CreateUser = "@quidproquo-core/UserDirectory/CreateUser",
@@ -23,7 +24,7 @@ export declare enum UserDirectoryActionType {
23
24
  export interface AuthenticationInfo {
24
25
  accessToken?: string;
25
26
  expirationDurationInSeconds?: number;
26
- expiresAt?: string;
27
+ expiresAt?: QpqIsoDateTime;
27
28
  idToken?: string;
28
29
  refreshToken?: string;
29
30
  tokenType?: string;
@@ -1,3 +1,3 @@
1
1
  export * from './QPQConfig';
2
2
  export * from './settings';
3
- export * from "./utils";
3
+ export * from './utils';
@@ -1,2 +1,2 @@
1
- export * from "./crossModuleUtils";
2
- export * from "./qpqFunctionRuntimeUtils";
1
+ export * from './crossModuleUtils';
2
+ export * from './qpqFunctionRuntimeUtils';
@@ -5,7 +5,7 @@ export * from './createImplementationRuntime';
5
5
  export * from './logic';
6
6
  export * from './logic/actionLogic';
7
7
  export * from './proiseify';
8
- export * from "./qpqCoreUtilsLib";
8
+ export * from './qpqCoreUtilsLib';
9
9
  export * from './qpqExecuteLog';
10
10
  export * from './runtime';
11
11
  export * from './stories';
@@ -62,7 +62,15 @@ const getProcessExecuteStory = (qpqConfig) => {
62
62
  return (0, actionLogic_1.actionResultError)(types_1.ErrorTypeEnum.NotFound, `Unable to dynamically load: [${payload.runtime}]`);
63
63
  }
64
64
  try {
65
- const qpqPromisifyRuntime = [payload, session, actionProcessors, logger, updateSession, dynamicModuleLoader, streamRegistry];
65
+ const qpqPromisifyRuntime = [
66
+ payload,
67
+ session,
68
+ actionProcessors,
69
+ logger,
70
+ updateSession,
71
+ dynamicModuleLoader,
72
+ streamRegistry,
73
+ ];
66
74
  const result = yield story(...payload.params, (0, exports.getRun)(qpqPromisifyRuntime));
67
75
  return (0, actionLogic_1.actionResult)(result);
68
76
  }
@@ -11,23 +11,40 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.resolveStoryWithLogs = resolveStoryWithLogs;
13
13
  const resolveStory_1 = require("./resolveStory");
14
+ let activeLogCollectors = [];
15
+ let unpatchedConsoleLog = null;
16
+ const pushLogCollector = (collector) => {
17
+ if (unpatchedConsoleLog === null) {
18
+ const original = console.log;
19
+ unpatchedConsoleLog = original;
20
+ console.log = (...args) => {
21
+ for (const active of activeLogCollectors) {
22
+ active.logs.push({ t: active.getTimeNow(), a: args });
23
+ }
24
+ return original(...args);
25
+ };
26
+ }
27
+ activeLogCollectors.push(collector);
28
+ };
29
+ const popLogCollector = (collector) => {
30
+ activeLogCollectors = activeLogCollectors.filter((active) => active !== collector);
31
+ if (activeLogCollectors.length === 0 && unpatchedConsoleLog !== null) {
32
+ console.log = unpatchedConsoleLog;
33
+ unpatchedConsoleLog = null;
34
+ }
35
+ };
14
36
  function resolveStoryWithLogs(story, args, qpqConfig, callerSession, getActionProcessors, getTimeNow, logger, runtimeCorrelation, runtimeType, dynamicModuleLoader, qpqFunctionRuntimeInfo, initialTags, streamRegistry) {
15
37
  return __awaiter(this, void 0, void 0, function* () {
16
- const logs = [];
17
- const oldConsoleLog = console.log;
38
+ const collector = { logs: [], getTimeNow };
18
39
  try {
19
- console.log = (...args) => {
20
- const logEntry = { t: getTimeNow(), a: args };
21
- logs.push(logEntry);
22
- return oldConsoleLog(...args);
23
- };
40
+ pushLogCollector(collector);
24
41
  const storyResult = yield (0, resolveStory_1.resolveStory)(story, args, qpqConfig, callerSession, getActionProcessors, getTimeNow, logger, runtimeCorrelation, runtimeType, dynamicModuleLoader, qpqFunctionRuntimeInfo, initialTags, streamRegistry);
25
- storyResult.logs = logs;
42
+ storyResult.logs = collector.logs;
26
43
  logger.log(storyResult);
27
44
  return storyResult;
28
45
  }
29
46
  finally {
30
- console.log = oldConsoleLog;
47
+ popLogCollector(collector);
31
48
  }
32
49
  });
33
50
  }
@@ -1,3 +1,7 @@
1
1
  import { AskResponse } from '../types';
2
2
  import { askCatch } from './system';
3
- export declare function askRetry<R>(askRunLogic: () => AskResponse<R>, maxRetries: number, timeToWaitMs: number, errorTypeRetryList?: string[]): ReturnType<typeof askCatch<AskResponse<R>>>;
3
+ export type AskRetryOptions = {
4
+ linearBackoff?: boolean;
5
+ maxJitterMs?: number;
6
+ };
7
+ export declare function askRetry<R>(askRunLogic: () => AskResponse<R>, maxRetries: number, timeToWaitMs: number, errorTypeRetryList?: string[], options?: AskRetryOptions): ReturnType<typeof askCatch<AskResponse<R>>>;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.askRetry = askRetry;
4
4
  const actions_1 = require("../actions");
5
5
  const system_1 = require("./system");
6
- function* askRetry(askRunLogic, maxRetries, timeToWaitMs, errorTypeRetryList) {
6
+ function* askRetry(askRunLogic, maxRetries, timeToWaitMs, errorTypeRetryList, options) {
7
7
  let attempt = 0;
8
8
  while (true) {
9
9
  const result = yield* (0, system_1.askCatch)(askRunLogic());
@@ -16,6 +16,11 @@ function* askRetry(askRunLogic, maxRetries, timeToWaitMs, errorTypeRetryList) {
16
16
  return result;
17
17
  }
18
18
  }
19
- yield* (0, actions_1.askDelay)(timeToWaitMs);
19
+ let waitMs = (options === null || options === void 0 ? void 0 : options.linearBackoff) ? timeToWaitMs * attempt : timeToWaitMs;
20
+ if (options === null || options === void 0 ? void 0 : options.maxJitterMs) {
21
+ const guid = yield* (0, actions_1.askNewGuid)();
22
+ waitMs += Math.floor((parseInt(guid.slice(0, 2), 16) / 255) * options.maxJitterMs);
23
+ }
24
+ yield* (0, actions_1.askDelay)(waitMs);
20
25
  }
21
26
  }
@@ -0,0 +1,23 @@
1
+ export type TYear = `${number}${number}${number}${number}`;
2
+ export type TMonth = `${number}${number}`;
3
+ export type TDay = `${number}${number}`;
4
+ export type THours = `${number}${number}`;
5
+ export type TMinutes = `${number}${number}`;
6
+ export type TSeconds = `${number}${number}`;
7
+ export type TMilliseconds = `${number}${number}${number}`;
8
+ /**
9
+ * Represent a string like `2021-01-08`
10
+ */
11
+ export type TDateISODate = `${TYear}-${TMonth}-${TDay}`;
12
+ /**
13
+ * Represent a string like `14:42:34.678`
14
+ */
15
+ export type TDateISOTime = `${THours}:${TMinutes}:${TSeconds}.${TMilliseconds}`;
16
+ /**
17
+ * Represent a string like `2021-01-08T14:42:34.678Z` (format: ISO 8601).
18
+ *
19
+ * It is not possible to type more precisely (list every possible values for months, hours etc) as
20
+ * it would result in a warning from TypeScript:
21
+ * "Expression produces a union type that is too complex to represent. ts(2590)
22
+ */
23
+ export type QpqIsoDateTime = `${TDateISODate}T${TDateISOTime}Z`;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ // Template-literal typing for ISO-8601 timestamps
3
+ // (from https://gist.github.com/MrChocolatine/367fb2a35d02f6175cc8ccb3d3a20054)
4
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -20,6 +20,7 @@ export * from './Nullable';
20
20
  export * from './QPQBinaryData';
21
21
  export * from './QpqContextIdentifier';
22
22
  export * from './QpqFunctionRuntime';
23
+ export * from './QpqIsoDateTime';
23
24
  export * from './QpqLogger';
24
25
  export * from './QpqPagedData';
25
26
  export * from './QueueEvent';
@@ -36,6 +36,7 @@ __exportStar(require("./Nullable"), exports);
36
36
  __exportStar(require("./QPQBinaryData"), exports);
37
37
  __exportStar(require("./QpqContextIdentifier"), exports);
38
38
  __exportStar(require("./QpqFunctionRuntime"), exports);
39
+ __exportStar(require("./QpqIsoDateTime"), exports);
39
40
  __exportStar(require("./QpqLogger"), exports);
40
41
  __exportStar(require("./QpqPagedData"), exports);
41
42
  __exportStar(require("./QueueEvent"), exports);
@@ -0,0 +1,2 @@
1
+ import { QpqIsoDateTime } from '../../types/QpqIsoDateTime';
2
+ export declare const getQpqIsoDateTimeFromDate: (date: Date) => QpqIsoDateTime;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getQpqIsoDateTimeFromDate = void 0;
4
+ const getQpqIsoDateTimeFromDate = (date) => date.toISOString();
5
+ exports.getQpqIsoDateTimeFromDate = getQpqIsoDateTimeFromDate;
@@ -0,0 +1,2 @@
1
+ import { QpqIsoDateTime } from '../../types/QpqIsoDateTime';
2
+ export declare const getValidQpqIsoDateTime: (value: string | undefined) => QpqIsoDateTime | undefined;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getValidQpqIsoDateTime = void 0;
4
+ const qpqIsoDateTimeRegex = /^\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d{3}Z$/;
5
+ const getValidQpqIsoDateTime = (value) => value && qpqIsoDateTimeRegex.test(value) ? value : undefined;
6
+ exports.getValidQpqIsoDateTime = getValidQpqIsoDateTime;
@@ -0,0 +1,2 @@
1
+ export * from './getQpqIsoDateTimeFromDate';
2
+ export * from './getValidQpqIsoDateTime';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./getQpqIsoDateTimeFromDate"), exports);
18
+ __exportStar(require("./getValidQpqIsoDateTime"), exports);
@@ -1 +1,2 @@
1
1
  export * from './generateSimpleHash';
2
+ export * from './sha1';
@@ -15,3 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./generateSimpleHash"), exports);
18
+ __exportStar(require("./sha1"), exports);
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Computes the SHA-1 digest of the given bytes.
3
+ *
4
+ * This is a pure TypeScript implementation (RFC 3174) so it stays synchronous and
5
+ * works in both Node and browsers without the async Web Crypto API or a Node-only
6
+ * `crypto` import. SHA-1 is not collision-resistant, so this must never be used for
7
+ * security purposes - it exists for deterministic identifiers like v5 UUIDs.
8
+ *
9
+ * @param {Uint8Array} message - The bytes to hash.
10
+ * @returns {Uint8Array} The 20-byte SHA-1 digest.
11
+ */
12
+ export declare function sha1(message: Uint8Array): Uint8Array;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sha1 = sha1;
4
+ /**
5
+ * Computes the SHA-1 digest of the given bytes.
6
+ *
7
+ * This is a pure TypeScript implementation (RFC 3174) so it stays synchronous and
8
+ * works in both Node and browsers without the async Web Crypto API or a Node-only
9
+ * `crypto` import. SHA-1 is not collision-resistant, so this must never be used for
10
+ * security purposes - it exists for deterministic identifiers like v5 UUIDs.
11
+ *
12
+ * @param {Uint8Array} message - The bytes to hash.
13
+ * @returns {Uint8Array} The 20-byte SHA-1 digest.
14
+ */
15
+ function sha1(message) {
16
+ // Pad to a multiple of 64 bytes: a 0x80 byte, zeros, then the 64-bit big-endian bit length.
17
+ const messageLength = message.length;
18
+ const paddedLength = Math.ceil((messageLength + 1 + 8) / 64) * 64;
19
+ const padded = new Uint8Array(paddedLength);
20
+ padded.set(message);
21
+ padded[messageLength] = 0x80;
22
+ const view = new DataView(padded.buffer);
23
+ const bitLength = messageLength * 8;
24
+ view.setUint32(paddedLength - 8, Math.floor(bitLength / 0x100000000));
25
+ view.setUint32(paddedLength - 4, bitLength >>> 0);
26
+ let h0 = 0x67452301;
27
+ let h1 = 0xefcdab89;
28
+ let h2 = 0x98badcfe;
29
+ let h3 = 0x10325476;
30
+ let h4 = 0xc3d2e1f0;
31
+ const w = new Uint32Array(80);
32
+ for (let block = 0; block < paddedLength; block += 64) {
33
+ for (let t = 0; t < 16; t++) {
34
+ w[t] = view.getUint32(block + t * 4);
35
+ }
36
+ for (let t = 16; t < 80; t++) {
37
+ const x = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16];
38
+ w[t] = (x << 1) | (x >>> 31);
39
+ }
40
+ let a = h0;
41
+ let b = h1;
42
+ let c = h2;
43
+ let d = h3;
44
+ let e = h4;
45
+ for (let t = 0; t < 80; t++) {
46
+ let f;
47
+ let k;
48
+ if (t < 20) {
49
+ f = (b & c) | (~b & d);
50
+ k = 0x5a827999;
51
+ }
52
+ else if (t < 40) {
53
+ f = b ^ c ^ d;
54
+ k = 0x6ed9eba1;
55
+ }
56
+ else if (t < 60) {
57
+ f = (b & c) | (b & d) | (c & d);
58
+ k = 0x8f1bbcdc;
59
+ }
60
+ else {
61
+ f = b ^ c ^ d;
62
+ k = 0xca62c1d6;
63
+ }
64
+ const temp = (((a << 5) | (a >>> 27)) + f + e + k + w[t]) >>> 0;
65
+ e = d;
66
+ d = c;
67
+ c = (b << 30) | (b >>> 2);
68
+ b = a;
69
+ a = temp;
70
+ }
71
+ h0 = (h0 + a) >>> 0;
72
+ h1 = (h1 + b) >>> 0;
73
+ h2 = (h2 + c) >>> 0;
74
+ h3 = (h3 + d) >>> 0;
75
+ h4 = (h4 + e) >>> 0;
76
+ }
77
+ const digest = new Uint8Array(20);
78
+ const digestView = new DataView(digest.buffer);
79
+ digestView.setUint32(0, h0);
80
+ digestView.setUint32(4, h1);
81
+ digestView.setUint32(8, h2);
82
+ digestView.setUint32(12, h3);
83
+ digestView.setUint32(16, h4);
84
+ return digest;
85
+ }
@@ -1,4 +1,5 @@
1
1
  export * from './array';
2
+ export * from './dateTime';
2
3
  export * from './functions';
3
4
  export * from './hash';
4
5
  export * from './logs';
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./array"), exports);
18
+ __exportStar(require("./dateTime"), exports);
18
19
  __exportStar(require("./functions"), exports);
19
20
  __exportStar(require("./hash"), exports);
20
21
  __exportStar(require("./logs"), exports);
@@ -0,0 +1,20 @@
1
+ export declare enum UuidNamespace {
2
+ dns = "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
3
+ url = "6ba7b811-9dad-11d1-80b4-00c04fd430c8",
4
+ oid = "6ba7b812-9dad-11d1-80b4-00c04fd430c8",
5
+ x500 = "6ba7b814-9dad-11d1-80b4-00c04fd430c8"
6
+ }
7
+ /**
8
+ * Generates a deterministic name-based (version 5) UUID - the sister of `generateUuid`.
9
+ *
10
+ * Where `generateUuid` mints a random v4 UUID, this derives a UUID from a name and a
11
+ * namespace UUID per RFC 4122: the same inputs always produce the same UUID, so it is
12
+ * useful for stable identifiers (e.g. mapping an external key to a UUID). It hashes with
13
+ * the bundled pure-TypeScript SHA-1 so it stays synchronous and dependency-free in both
14
+ * Node and browsers.
15
+ *
16
+ * @param {string} name - The name to derive the UUID from.
17
+ * @param {string} namespace - The namespace UUID, e.g. `UuidNamespace.dns` or any UUID of your own.
18
+ * @returns {string} The derived v5 UUID, e.g. `2ed6657d-e927-568b-95e1-2665a8aea6a2`.
19
+ */
20
+ export declare function generateUuidV5(name: string, namespace: string): string;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UuidNamespace = void 0;
4
+ exports.generateUuidV5 = generateUuidV5;
5
+ const sha1_1 = require("../hash/sha1");
6
+ // The well-known namespace UUIDs from RFC 4122 Appendix C.
7
+ var UuidNamespace;
8
+ (function (UuidNamespace) {
9
+ UuidNamespace["dns"] = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
10
+ UuidNamespace["url"] = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
11
+ UuidNamespace["oid"] = "6ba7b812-9dad-11d1-80b4-00c04fd430c8";
12
+ UuidNamespace["x500"] = "6ba7b814-9dad-11d1-80b4-00c04fd430c8";
13
+ })(UuidNamespace || (exports.UuidNamespace = UuidNamespace = {}));
14
+ const uuidFormatRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
15
+ const uuidToBytes = (uuid) => {
16
+ const hex = uuid.replace(/-/g, '');
17
+ const bytes = new Uint8Array(16);
18
+ for (let i = 0; i < 16; i++) {
19
+ bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
20
+ }
21
+ return bytes;
22
+ };
23
+ const bytesToUuid = (bytes) => {
24
+ const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
25
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
26
+ };
27
+ /**
28
+ * Generates a deterministic name-based (version 5) UUID - the sister of `generateUuid`.
29
+ *
30
+ * Where `generateUuid` mints a random v4 UUID, this derives a UUID from a name and a
31
+ * namespace UUID per RFC 4122: the same inputs always produce the same UUID, so it is
32
+ * useful for stable identifiers (e.g. mapping an external key to a UUID). It hashes with
33
+ * the bundled pure-TypeScript SHA-1 so it stays synchronous and dependency-free in both
34
+ * Node and browsers.
35
+ *
36
+ * @param {string} name - The name to derive the UUID from.
37
+ * @param {string} namespace - The namespace UUID, e.g. `UuidNamespace.dns` or any UUID of your own.
38
+ * @returns {string} The derived v5 UUID, e.g. `2ed6657d-e927-568b-95e1-2665a8aea6a2`.
39
+ */
40
+ function generateUuidV5(name, namespace) {
41
+ if (!uuidFormatRegex.test(namespace)) {
42
+ throw new Error(`Invalid namespace UUID [${namespace}]`);
43
+ }
44
+ const namespaceBytes = uuidToBytes(namespace);
45
+ const nameBytes = new TextEncoder().encode(name);
46
+ const input = new Uint8Array(namespaceBytes.length + nameBytes.length);
47
+ input.set(namespaceBytes);
48
+ input.set(nameBytes, namespaceBytes.length);
49
+ const bytes = (0, sha1_1.sha1)(input).slice(0, 16);
50
+ // RFC 4122: the high nibble of byte 6 carries the version, the top bits of byte 8 the variant.
51
+ bytes[6] = (bytes[6] & 0x0f) | 0x50;
52
+ bytes[8] = (bytes[8] & 0x3f) | 0x80;
53
+ return bytesToUuid(bytes);
54
+ }
@@ -1 +1,2 @@
1
1
  export * from './generateUuid';
2
+ export * from './generateUuidV5';
@@ -15,3 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./generateUuid"), exports);
18
+ __exportStar(require("./generateUuidV5"), exports);