@arkstack/common 0.15.5 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -345,6 +345,15 @@ type HookFor<N extends string> = N extends keyof HookRegistry ? HookRegistry[N]
345
345
  type HookPos<N extends string, P extends string> = N extends keyof HookRegistry ? P extends keyof HookRegistry[N] ? HookRegistry[N][P] : (...args: any[]) => void : (...args: any[]) => void;
346
346
  type HookPositions<N extends string> = N extends keyof HookRegistry ? keyof HookRegistry[N] : Position;
347
347
  type HookArgs<N extends string, P extends string> = N extends keyof HookRegistry ? P extends keyof HookRegistry[N] ? HookRegistry[N][P] extends ((...args: infer A) => any) ? A : any[] : any[] : any[];
348
+ type Choice<Value> = {
349
+ value: Value;
350
+ name?: string;
351
+ description?: string;
352
+ short?: string;
353
+ disabled?: boolean | string;
354
+ type?: never;
355
+ };
356
+ type Choices = readonly string[] | readonly Choice<string>[];
348
357
  /**
349
358
  * A single source → destination mapping a package wants to publish into the
350
359
  * consuming application.
@@ -362,7 +371,9 @@ interface PublishEntry {
362
371
  * A group of publishable artifacts registered by a package.
363
372
  */
364
373
  interface PublishGroup {
365
- /** The package registering the artifacts, e.g. `@arkstack/cache`. */
374
+ /**
375
+ * The package registering the artifacts, e.g. `@arkstack/cache`.
376
+ */
366
377
  package: string;
367
378
  /**
368
379
  * Optional tag for selective publishing (`ark publish --tag <tag>`). A
@@ -377,6 +388,30 @@ interface PublishFilter {
377
388
  package?: string;
378
389
  tag?: string;
379
390
  }
391
+ /** Optional filter applied when reading the registry. */
392
+ interface PublishConfirmation {
393
+ /**
394
+ * The package registering the confirmation, e.g. `@arkstack/cache`.
395
+ */
396
+ package: string;
397
+ /**
398
+ * A message describing what the confirmation is
399
+ * for, e.g. "Are you sure you want to publish the cache migrations?"
400
+ */
401
+ message: string;
402
+ /**
403
+ * Options to choose from.
404
+ */
405
+ options: Choices;
406
+ /**
407
+ * A callback function to handle the selected choice and the stub file.
408
+ *
409
+ * @param choice
410
+ * @param stub
411
+ * @returns
412
+ */
413
+ callback?: (choice: Choice<string>['value'], stub: string) => string | Promise<string>;
414
+ }
380
415
  //#endregion
381
416
  //#region src/system.d.ts
382
417
  /**
@@ -629,7 +664,13 @@ declare const logUnhandledError: typeof ErrorHandler.logUnhandledError;
629
664
  * shared instance even across duplicated module copies.
630
665
  */
631
666
  declare class Publisher {
632
- /** The shared, global-symbol-backed registry of publishable groups. */
667
+ /**
668
+ * The shared, global-symbol-backed registry of publishable groups confirmations.
669
+ */
670
+ private static get confirmations();
671
+ /**
672
+ * The shared, global-symbol-backed registry of publishable groups.
673
+ */
633
674
  private static get registry();
634
675
  /**
635
676
  * Register artifacts a package wants to publish into the application.
@@ -654,8 +695,24 @@ declare class Publisher {
654
695
  * @returns The matching publishable groups.
655
696
  */
656
697
  static publishables(filter?: PublishFilter): PublishGroup[];
657
- /** Remove every registered publishable group (primarily for tests). */
698
+ /**
699
+ * Remove every registered publishable group and confirmation (primarily for
700
+ * tests).
701
+ */
658
702
  static clear(): void;
703
+ /**
704
+ * Ask to confirm what tag needs to be published.
705
+ *
706
+ * @param confirmation
707
+ */
708
+ static confirm(confirmation: PublishConfirmation | PublishConfirmation[]): void;
709
+ /**
710
+ * Read the registered confirmable groups
711
+ *
712
+ * @param pkg The package for which to find confirmations.
713
+ * @returns The matching confirmables groups.
714
+ */
715
+ static confirmables(pkg: string | true): PublishConfirmation[];
659
716
  }
660
717
  //#endregion
661
718
  //#region src/Hook.d.ts
@@ -813,4 +870,4 @@ declare const devTlsCredentials: (host?: string) => Promise<TlsCredentials>;
813
870
  */
814
871
  declare const localNetworkAddress: () => string | undefined;
815
872
  //#endregion
816
- export { AbstractModelConstructor, AppConfig, AppException, ArkstackErrorPayload, ArkstackErrorShape, CONFIG_KEY, ConfigLoader, ConfigRegistry, ConfigShape, DotPath, DotPathValue, Encryption, EnvKey, EnvLoader, EnvLookup, EnvRegistry, EnvReturn, ErrorHandler, Exception, FileImporter, GlobalConfig, GlobalEnv, Hash, Hook, HookArgs, HookFor, HookName, HookPos, HookPositions, HookRegistry, IHook, Logger, LoggerChalk, LoggerLog, LoggerParseSignature, MergedConfig, ModelConstructor, ModelRegistry, Primitive, PublishEntry, PublishFilter, PublishGroup, Publisher, RequestException, TlsCredentials, UnionToIntersection, abort, abortIf, appKey, appUrl, assertFound, bindGracefulShutdown, bootWithDetectedPort, config, configLoader, createErrorPayload, devTlsCredentials, discoverCommands, env, envLoader, getErrorLogger, getModel, getPrimaryError, getValidationErrors, importFile, initializeGlobalContext, interopDefault, isClass, isModelNotFoundError, isValidationError, loadPrototypes, localNetworkAddress, logUnhandledError, nodeEnv, normalizeStatusCode, outputDir, perPage, rebuildOutput, renderError, resolveRuntimeDir, resolveRuntimeModule, serializeError, shouldHideStack, shouldLogError, toErrorShape, toOutputPath };
873
+ export { AbstractModelConstructor, AppConfig, AppException, ArkstackErrorPayload, ArkstackErrorShape, CONFIG_KEY, Choice, Choices, ConfigLoader, ConfigRegistry, ConfigShape, DotPath, DotPathValue, Encryption, EnvKey, EnvLoader, EnvLookup, EnvRegistry, EnvReturn, ErrorHandler, Exception, FileImporter, GlobalConfig, GlobalEnv, Hash, Hook, HookArgs, HookFor, HookName, HookPos, HookPositions, HookRegistry, IHook, Logger, LoggerChalk, LoggerLog, LoggerParseSignature, MergedConfig, ModelConstructor, ModelRegistry, Primitive, PublishConfirmation, PublishEntry, PublishFilter, PublishGroup, Publisher, RequestException, TlsCredentials, UnionToIntersection, abort, abortIf, appKey, appUrl, assertFound, bindGracefulShutdown, bootWithDetectedPort, config, configLoader, createErrorPayload, devTlsCredentials, discoverCommands, env, envLoader, getErrorLogger, getModel, getPrimaryError, getValidationErrors, importFile, initializeGlobalContext, interopDefault, isClass, isModelNotFoundError, isValidationError, loadPrototypes, localNetworkAddress, logUnhandledError, nodeEnv, normalizeStatusCode, outputDir, perPage, rebuildOutput, renderError, resolveRuntimeDir, resolveRuntimeModule, serializeError, shouldHideStack, shouldLogError, toErrorShape, toOutputPath };
package/dist/index.js CHANGED
@@ -1,10 +1,9 @@
1
1
  import { _ as ConfigLoader, a as env, c as nodeEnv, d as resolveRuntimeDir, f as resolveRuntimeModule, g as CONFIG_KEY, h as envLoader, i as discoverCommands, l as outputDir, m as EnvLoader, n as appUrl, o as importFile, p as toOutputPath, r as config, s as interopDefault, t as appKey, u as rebuildOutput, v as configLoader } from "./system-BRlEuM_u.js";
2
- import { _ as Hash, c as abortIf, d as initializeGlobalContext, f as isClass, g as Exception, h as AppException, l as assertFound, m as RequestException, p as perPage, s as abort, u as getModel, v as Encryption } from "./utils-DH3mXX5o.js";
2
+ import { _ as Hash, c as abortIf, d as initializeGlobalContext, f as isClass, g as Exception, h as AppException, l as assertFound, m as RequestException, p as perPage, s as abort, u as getModel, v as Encryption } from "./utils-BbOOTGzA.js";
3
3
  import { Hook as Hook$1 } from "@arkstack/foundry";
4
4
  import { Arkstack } from "@arkstack/contract";
5
5
  import { str } from "@h3ravel/support";
6
6
  import path from "node:path";
7
- import { ModelNotFoundException } from "arkormx";
8
7
  import { detect } from "detect-port";
9
8
  import pino from "pino";
10
9
  import chalk from "chalk";
@@ -150,11 +149,12 @@ var ErrorHandler = class ErrorHandler {
150
149
  }
151
150
  static isModelNotFoundError(error) {
152
151
  const candidate = ErrorHandler.toErrorShape(error);
153
- if (error.cause && error.cause instanceof ModelNotFoundException) {
154
- error.getModelName = error.cause.getModelName;
152
+ const cause = error?.cause;
153
+ if (cause && typeof cause.getModelName === "function") {
154
+ error.getModelName = cause.getModelName;
155
155
  return true;
156
156
  }
157
- return typeof candidate?.getModelName === "function" || error instanceof ModelNotFoundException;
157
+ return typeof candidate?.getModelName === "function";
158
158
  }
159
159
  static shouldHideStack() {
160
160
  const value = process.env.HIDE_ERROR_STACK;
@@ -215,6 +215,7 @@ const logUnhandledError = ErrorHandler.logUnhandledError;
215
215
  //#endregion
216
216
  //#region src/Publisher.ts
217
217
  const REGISTRY_KEY = Symbol.for("arkstack.publishables");
218
+ const CONFIRMATION_REGISTRY_KEY = Symbol.for("arkstack.confirmables");
218
219
  /**
219
220
  * Registry of artifacts packages want to publish into the consuming application.
220
221
  *
@@ -224,7 +225,15 @@ const REGISTRY_KEY = Symbol.for("arkstack.publishables");
224
225
  * shared instance even across duplicated module copies.
225
226
  */
226
227
  var Publisher = class {
227
- /** The shared, global-symbol-backed registry of publishable groups. */
228
+ /**
229
+ * The shared, global-symbol-backed registry of publishable groups confirmations.
230
+ */
231
+ static get confirmations() {
232
+ return globalThis[CONFIRMATION_REGISTRY_KEY] ??= [];
233
+ }
234
+ /**
235
+ * The shared, global-symbol-backed registry of publishable groups.
236
+ */
228
237
  static get registry() {
229
238
  return globalThis[REGISTRY_KEY] ??= [];
230
239
  }
@@ -255,9 +264,30 @@ var Publisher = class {
255
264
  static publishables(filter = {}) {
256
265
  return this.registry.filter((group) => (!filter.package || group.package === filter.package) && (!filter.tag || group.tag === filter.tag));
257
266
  }
258
- /** Remove every registered publishable group (primarily for tests). */
267
+ /**
268
+ * Remove every registered publishable group and confirmation (primarily for
269
+ * tests).
270
+ */
259
271
  static clear() {
260
272
  this.registry.length = 0;
273
+ this.confirmations.length = 0;
274
+ }
275
+ /**
276
+ * Ask to confirm what tag needs to be published.
277
+ *
278
+ * @param confirmation
279
+ */
280
+ static confirm(confirmation) {
281
+ this.confirmations.push(...Array.isArray(confirmation) ? confirmation : [confirmation]);
282
+ }
283
+ /**
284
+ * Read the registered confirmable groups
285
+ *
286
+ * @param pkg The package for which to find confirmations.
287
+ * @returns The matching confirmables groups.
288
+ */
289
+ static confirmables(pkg) {
290
+ return this.confirmations.filter((group) => typeof pkg === "boolean" ? pkg : pkg === group.package);
261
291
  }
262
292
  };
263
293
  //#endregion
@@ -1,2 +1,2 @@
1
- import { _ as Hash, a as use, c as abortIf, d as initializeGlobalContext, f as isClass, i as trait, l as assertFound, n as crc32, o as uses, p as perPage, r as getTraitMethods, s as abort, t as callTraitMethods, u as getModel, v as Encryption } from "../utils-DH3mXX5o.js";
1
+ import { _ as Hash, a as use, c as abortIf, d as initializeGlobalContext, f as isClass, i as trait, l as assertFound, n as crc32, o as uses, p as perPage, r as getTraitMethods, s as abort, t as callTraitMethods, u as getModel, v as Encryption } from "../utils-BbOOTGzA.js";
2
2
  export { Encryption, Hash, abort, abortIf, assertFound, callTraitMethods, crc32, getModel, getTraitMethods, initializeGlobalContext, isClass, perPage, trait, use, uses };
@@ -4,7 +4,6 @@ import { Arkstack } from "@arkstack/contract";
4
4
  import path from "node:path";
5
5
  import { Secret, TOTP } from "otpauth";
6
6
  import { compare, genSalt, hash } from "bcryptjs";
7
- import { getUserConfig } from "arkormx";
8
7
  //#region src/utils/encryption.ts
9
8
  var Encryption = class {
10
9
  static algorithm = "aes-256-gcm";
@@ -186,6 +185,7 @@ async function getModel(modelName) {
186
185
  return module.default ?? module[modelName] ?? module;
187
186
  };
188
187
  const isModelModule = (value) => typeof value === "object" && value !== null;
188
+ const { getUserConfig } = await import("arkormx");
189
189
  const modelPath = getUserConfig().paths?.models || "./src/models";
190
190
  const model = resolveModelExport(await importFile(resolveRuntimeModule(path.join(path.isAbsolute(modelPath) ? modelPath : path.join(Arkstack.rootDir(), modelPath), modelName))), path.basename(modelName, path.extname(modelName)));
191
191
  if (typeof model !== "function") throw new Error(`Model "${modelName}" not found`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkstack/common",
3
- "version": "0.15.5",
3
+ "version": "0.16.1",
4
4
  "type": "module",
5
5
  "description": "Core utilities, primitives, and shared infrastructure for the Arkstack ecosystem.",
6
6
  "homepage": "https://arkstack.toneflix.net",
@@ -44,10 +44,10 @@
44
44
  "selfsigned": "^2.4.1"
45
45
  },
46
46
  "peerDependencies": {
47
- "@h3ravel/support": "^2.2.0",
47
+ "@h3ravel/support": "^2.2.1",
48
48
  "arkormx": "^2.10.1",
49
- "@arkstack/contract": "^0.15.5",
50
- "@arkstack/foundry": "^0.15.5"
49
+ "@arkstack/foundry": "^0.16.1",
50
+ "@arkstack/contract": "^0.16.1"
51
51
  },
52
52
  "optionalDependencies": {
53
53
  "@faker-js/faker": "^10.4.0"