@empyria/common 0.1.0 → 0.1.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/AGENTS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # AGENTS.md
2
2
 
3
- Shared backend services for higher-level components in **Principia**, a nanoservice
3
+ Shared backend services for higher-level components in **Empyria**, a nanoservice
4
4
  framework built primarily on Bun: environment variable schemas, error definitions,
5
5
  Codogram (SMS/TOTP-style challenge codes), and Ata (JSON schema + validation).
6
6
 
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @empyria/common
2
2
 
3
- Shared backend services for higher-level components in **Principia**, a nanoservice
3
+ Shared backend services for higher-level components in **Empyria**, a nanoservice
4
4
  framework built primarily on Bun: environment variable schemas, error definitions,
5
5
  Codogram (SMS/TOTP-style challenge codes), and Ata (JSON schema building blocks and
6
6
  validation).
@@ -43,9 +43,9 @@ import { defineSchema } from '@empyria/common/lib/Ata.js'
43
43
 
44
44
  | Module | Purpose |
45
45
  | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
46
- | [index.js](./index.js) | Package entry point; re-exports every module below plus Moleculer meta helpers (`moleculerMeta`, `moleculerPrincipiaMeta`) and workflow ID helpers (`workflowName`, `workflowId`, `identifyWorkflow`). |
47
- | [lib/Errors.js](./lib/Errors.js) | `PrincipiaError`, the `ErrorCreator` factory, and `BaseErrors` — Principia's catalog of pre-built, templated errors. |
48
- | [lib/Env.js](./lib/Env.js) | `createEnv` — builds a service's environment-variable JSON schema from Principia-wide defaults. |
46
+ | [index.js](./index.js) | Package entry point; re-exports every module below plus Moleculer meta helpers (`moleculerMeta`, `moleculerEmpyriaMeta`) and workflow ID helpers (`workflowName`, `workflowId`, `identifyWorkflow`). |
47
+ | [lib/Errors.js](./lib/Errors.js) | `EmpyriaError`, the `ErrorCreator` factory, and `BaseErrors` — Empyria's catalog of pre-built, templated errors. |
48
+ | [lib/Env.js](./lib/Env.js) | `createEnv` — builds a service's environment-variable JSON schema from Empyria-wide defaults. |
49
49
  | [lib/Ata.js](./lib/Ata.js) | JSON schema building blocks (`string`, `number`, `bool`, `enumType`, `email`, `password`, `ip4`, `ip6`, ...) and validation (`defineSchema`, `createValidator`, `validate`), built on [ata-validator](https://www.npmjs.com/package/ata-validator). |
50
50
  | [lib/Codogram.js](./lib/Codogram.js) | `generateCodogram` — one-time challenge codes (PIN, alphanumeric, alphabetic) for SMS/TOTP-style verification flows. |
51
51
  | [lib/Defaulter.js](./lib/Defaulter.js) | `defaultsFromSchema` — builds a fully-populated default object for a JSON schema. |
package/index.js CHANGED
@@ -2,7 +2,7 @@ import { randomUUID as uuid } from 'node:crypto'
2
2
 
3
3
  import { TRANS } from '@empyria/classification'
4
4
 
5
- import { PrincipiaError, ErrorCreator, BaseErrors } from './lib/Errors.js'
5
+ import { EmpyriaError, ErrorCreator, BaseErrors } from './lib/Errors.js'
6
6
  import { createEnv } from './lib/Env.js'
7
7
 
8
8
  export * from './lib/Ata.js'
@@ -11,17 +11,17 @@ export * from './lib/Codogram.js'
11
11
 
12
12
  export * from './lib/Defaulter.js'
13
13
 
14
- export { PrincipiaError, ErrorCreator, BaseErrors, createEnv }
14
+ export { EmpyriaError, ErrorCreator, BaseErrors, createEnv }
15
15
 
16
- /** Role tag Moleculer assigns to every Principia microservice. */
16
+ /** Role tag Moleculer assigns to every Empyria microservice. */
17
17
  export const MOLECULER_SERVICE_ROLE = 'microservice'
18
18
 
19
19
  /** The federation's own actor/federation ID, used for system-originated calls. */
20
- export const PRINCIPIA_FEDERATION_ID =
21
- process.env.PRINCIPIA_FEDERATION_ID ?? '563ac2a1-3fe3-4c5f-b20f-6f33e5cbd680'
20
+ export const EMPYRIA_FEDERATION_ID =
21
+ process.env.EMPYRIA_FEDERATION_ID ?? '563ac2a1-3fe3-4c5f-b20f-6f33e5cbd680'
22
22
 
23
23
  /**
24
- * Builds a Moleculer call-context `meta` object carrying Principia's actor/tracing fields.
24
+ * Builds a Moleculer call-context `meta` object carrying Empyria's actor/tracing fields.
25
25
  * @param {Object} params
26
26
  * @param {string} params.actor - ID of the user/service making the call.
27
27
  * @param {string} params.federation - Federation the call belongs to.
@@ -45,7 +45,7 @@ export function moleculerMeta({ actor, federation, flowID, processID, role, toke
45
45
  }
46
46
 
47
47
  /**
48
- * Builds a {@link moleculerMeta} object for a system-originated (Principia-as-actor) call,
48
+ * Builds a {@link moleculerMeta} object for a system-originated (Empyria-as-actor) call,
49
49
  * generating a `flowID`/`processID` when not supplied.
50
50
  * @param {Object} params
51
51
  * @param {string} [params.flowID] - Flow correlation ID; a new UUID is generated if omitted.
@@ -53,10 +53,10 @@ export function moleculerMeta({ actor, federation, flowID, processID, role, toke
53
53
  * @param {string} params.tokenKey - Auth token key for the call.
54
54
  * @returns {ReturnType<typeof moleculerMeta>}
55
55
  */
56
- export function moleculerPrincipiaMeta({ flowID, processID, tokenKey }) {
56
+ export function moleculerEmpyriaMeta({ flowID, processID, tokenKey }) {
57
57
  return moleculerMeta({
58
- actor: PRINCIPIA_FEDERATION_ID,
59
- federation: PRINCIPIA_FEDERATION_ID,
58
+ actor: EMPYRIA_FEDERATION_ID,
59
+ federation: EMPYRIA_FEDERATION_ID,
60
60
  flowID: flowID ?? uuid(),
61
61
  processID: processID ?? uuid(),
62
62
  role: MOLECULER_SERVICE_ROLE,
@@ -88,12 +88,12 @@ export function workflowId(workflow) {
88
88
  * Parses a workflow ID (as produced by {@link workflowId}) back into its service/handler.
89
89
  * @param {string} workflowId - A `"SERVICE:HANDLER:<uuid>"`-shaped ID.
90
90
  * @returns {{service: string, handler: string}}
91
- * @throws {PrincipiaError} If `workflowId` doesn't have at least three `:`-separated components.
91
+ * @throws {EmpyriaError} If `workflowId` doesn't have at least three `:`-separated components.
92
92
  */
93
93
  export const identifyWorkflow = (workflowId) => {
94
94
  const components = workflowId?.split(':')
95
95
  if (!components || components.length < 3) {
96
- throw new PrincipiaError('Invalid workflow ID format')
96
+ throw new EmpyriaError('Invalid workflow ID format')
97
97
  }
98
98
  return {
99
99
  service: components[0],
package/lib/Ata.js CHANGED
@@ -67,7 +67,7 @@ export function defineSchema(schemaDef, options = {}) {
67
67
  * strict: a schema expecting `type: 'number'` rejects `"32"`. Pass `{ coerceTypes: true }`
68
68
  * for input that's inherently string-typed, such as `process.env` (see `createEnv`).
69
69
  * @returns {(data: *) => *} Function that returns `data` unchanged if valid.
70
- * @throws {PrincipiaError} `BaseErrors.ValidationError` (with a pretty-rendered violation list
70
+ * @throws {EmpyriaError} `BaseErrors.ValidationError` (with a pretty-rendered violation list
71
71
  * in its `validation` param) if `data` doesn't satisfy the schema.
72
72
  */
73
73
  export function createValidator(schema, options) {
@@ -92,7 +92,7 @@ export function createValidator(schema, options) {
92
92
  * @param {*} input - Value to validate.
93
93
  * @param {Object} [options] - Forwarded to {@link createValidator} (see its docs).
94
94
  * @returns {*} `input` unchanged, if valid.
95
- * @throws {PrincipiaError} `BaseErrors.ValidationError` if `input` doesn't satisfy the schema.
95
+ * @throws {EmpyriaError} `BaseErrors.ValidationError` if `input` doesn't satisfy the schema.
96
96
  */
97
97
  export function validate(schema, input, options) {
98
98
  const validateInput = createValidator(schema, options)
package/lib/Codogram.js CHANGED
@@ -3,7 +3,7 @@ import { enumise } from '@empyria/classification'
3
3
  import Clerobee from 'clerobee'
4
4
  import { BaseErrors } from './Errors.js'
5
5
 
6
- const clerobee = new Clerobee(process.env.PRINCIPIA_ID_LENGTH || 32)
6
+ const clerobee = new Clerobee(process.env.EMPYRIA_ID_LENGTH || 32)
7
7
 
8
8
  const CPIN = 'PIN'
9
9
  const CODE = 'Code'
@@ -26,7 +26,7 @@ const CABN_LENGTH = 6
26
26
  * @param {Object} [options={}]
27
27
  * @param {number} [options.length] - Overrides the type's default length.
28
28
  * @returns {number|string} A numeric PIN for `'PIN'`, otherwise an upper-cased string.
29
- * @throws {PrincipiaError} `BaseErrors.UnrecognisedType` if `type` isn't one of {@link CODOGRAM_LIST}.
29
+ * @throws {EmpyriaError} `BaseErrors.UnrecognisedType` if `type` isn't one of {@link CODOGRAM_LIST}.
30
30
  */
31
31
  export function generateCodogram(type, options = {}) {
32
32
  switch (type) {
package/lib/Env.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { defineSchema, bool, number, tmpFile, string, logLevel, logFile, nodeEnv } from './Ata.js'
2
2
 
3
- /** Environment schema shared by every Principia microservice. */
3
+ /** Environment schema shared by every Empyria microservice. */
4
4
  const DEFAULT_SERVICE_SCHEMA = {
5
- PRINCIPIA_ID_LENGTH: number(32),
5
+ EMPYRIA_ID_LENGTH: number(32),
6
6
 
7
7
  TMP_FOLDER: tmpFile(),
8
8
 
@@ -16,7 +16,7 @@ const DEFAULT_SERVICE_SCHEMA = {
16
16
  MOLECULER_TRANSPORTER: string('TCP'),
17
17
 
18
18
  MOLECULER_CACHE_ENABLED: bool(false),
19
- MOLECULER_CACHE_PREFIX: string('Principia'),
19
+ MOLECULER_CACHE_PREFIX: string('Empyria'),
20
20
  MOLECULER_CACHE_URL: string('redis://redis:6379/15'),
21
21
 
22
22
  RESTATE_ADMIN_URL: string('http://restate:9070'),
@@ -25,7 +25,7 @@ const DEFAULT_SERVICE_SCHEMA = {
25
25
 
26
26
  /**
27
27
  * Builds a JSON schema for a microservice's environment variables, merging the
28
- * Principia-wide defaults with any service-specific additions/overrides.
28
+ * Empyria-wide defaults with any service-specific additions/overrides.
29
29
  * @param {Object} [specificSchema] - Additional or overriding property schemas, keyed by env var name.
30
30
  * @returns {Object} A JSON schema object (see `defineSchema` in `./Ata.js`).
31
31
  */
package/lib/Errors.js CHANGED
@@ -3,20 +3,20 @@ import { inherits } from 'util'
3
3
  import { templating } from '@empyria/classification'
4
4
 
5
5
  /**
6
- * Principia's base error type. Carries a machine-readable `errorName`/`errorCode`
6
+ * Empyria's base error type. Carries a machine-readable `errorName`/`errorCode`
7
7
  * alongside the usual `message`, and captures its own stack trace.
8
8
  * @constructor
9
9
  * @param {string} message - Human-readable error message.
10
10
  * @param {string} [errorName] - Machine-readable error identifier.
11
11
  * @param {number} [errorCode] - Numeric error code.
12
12
  */
13
- let PrincipiaError = function (message, errorName, errorCode) {
13
+ let EmpyriaError = function (message, errorName, errorCode) {
14
14
  this.message = message
15
15
  this.errorName = errorName
16
16
  this.errorCode = errorCode
17
- Error.captureStackTrace(this, PrincipiaError)
17
+ Error.captureStackTrace(this, EmpyriaError)
18
18
  }
19
- inherits(PrincipiaError, Error)
19
+ inherits(EmpyriaError, Error)
20
20
 
21
21
  /**
22
22
  * Builds a reusable error factory from a template.
@@ -25,8 +25,8 @@ inherits(PrincipiaError, Error)
25
25
  * @param {string} [options.errorName] - Machine-readable error identifier.
26
26
  * @param {string} [options.message] - Message template with `{param}` placeholders (see
27
27
  * `templating` in `@empyria/classification`).
28
- * @returns {(opts?: Object) => PrincipiaError} Function that, given template values, returns a
29
- * new {@link PrincipiaError} with its `message` filled in and `params` set to the values used.
28
+ * @returns {(opts?: Object) => EmpyriaError} Function that, given template values, returns a
29
+ * new {@link EmpyriaError} with its `message` filled in and `params` set to the values used.
30
30
  */
31
31
  let ErrorCreator = function (options = {}) {
32
32
  let errorCode = options.errorCode
@@ -37,7 +37,7 @@ let ErrorCreator = function (options = {}) {
37
37
  let fnc = function (opts = {}) {
38
38
  let newArgs = Object.assign({}, args, opts)
39
39
  let message = templating(options.message, newArgs)
40
- let resultError = new PrincipiaError(message, options.errorName || errorCode, errorCode)
40
+ let resultError = new EmpyriaError(message, options.errorName || errorCode, errorCode)
41
41
  resultError.params = newArgs
42
42
  return resultError
43
43
  }
@@ -45,10 +45,10 @@ let ErrorCreator = function (options = {}) {
45
45
  }
46
46
 
47
47
  /**
48
- * Principia's catalog of pre-built error factories, one per well-known failure case.
48
+ * Empyria's catalog of pre-built error factories, one per well-known failure case.
49
49
  * Each entry is a function built via {@link ErrorCreator} — call it with the template's
50
50
  * parameters (e.g. `BaseErrors.EntityInvalid({ type: 'User', id: 42 })`) to get a
51
- * {@link PrincipiaError} instance ready to `throw`.
51
+ * {@link EmpyriaError} instance ready to `throw`.
52
52
  */
53
53
  let BaseErrors = {
54
54
  InvalidModel: ErrorCreator({
@@ -74,7 +74,7 @@ let BaseErrors = {
74
74
  NotInited: ErrorCreator({
75
75
  errorCode: 599997,
76
76
  errorName: 'NotInited',
77
- message: 'Principia is not inited',
77
+ message: 'Empyria is not inited',
78
78
  }),
79
79
  UnImplemented: ErrorCreator({
80
80
  errorCode: 599998,
@@ -163,4 +163,4 @@ let BaseErrors = {
163
163
  }),
164
164
  }
165
165
 
166
- export { PrincipiaError, ErrorCreator, BaseErrors }
166
+ export { EmpyriaError, ErrorCreator, BaseErrors }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@empyria/common",
3
- "version": "0.1.0",
4
- "description": "Shared backend goodies for Principia",
3
+ "version": "0.1.1",
4
+ "description": "Shared backend goodies for Empyria",
5
5
  "license": "MIT",
6
6
  "author": "Imre Fazekas <imre.fazekas@icloud.com>",
7
7
  "repository": {
@@ -19,7 +19,7 @@
19
19
  "test:watch": "bun test --watch"
20
20
  },
21
21
  "dependencies": {
22
- "@empyria/classification": "0.1.0",
22
+ "@empyria/classification": "0.1.1",
23
23
  "ata-validator": "1.6.1",
24
24
  "clerobee": "1.0.8",
25
25
  "ms": "2.1.3"
package/test/Ata.test.js CHANGED
@@ -22,7 +22,7 @@ import {
22
22
  renderCompact,
23
23
  renderJSON,
24
24
  } from '../lib/Ata.js'
25
- import { PrincipiaError } from '../lib/Errors.js'
25
+ import { EmpyriaError } from '../lib/Errors.js'
26
26
 
27
27
  describe('P_EMAIL', () => {
28
28
  const re = new RegExp(`^${P_EMAIL}`, 'i')
@@ -103,12 +103,12 @@ describe('createValidator / validate', () => {
103
103
  expect(validate(schema, { name: 'Bob' })).toEqual({ name: 'Bob' })
104
104
  })
105
105
 
106
- test('throws a PrincipiaError with a rendered message when invalid', () => {
106
+ test('throws a EmpyriaError with a rendered message when invalid', () => {
107
107
  try {
108
108
  validate(schema, {})
109
109
  throw new Error('should have thrown')
110
110
  } catch (err) {
111
- expect(err).toBeInstanceOf(PrincipiaError)
111
+ expect(err).toBeInstanceOf(EmpyriaError)
112
112
  expect(err.errorName).toBe('ValidationError')
113
113
  expect(err.message).toContain('name')
114
114
  }
@@ -116,7 +116,7 @@ describe('createValidator / validate', () => {
116
116
 
117
117
  test('is strict by default: a numeric string is rejected for a number schema', () => {
118
118
  const numSchema = defineSchema({ port: number() })
119
- expect(() => validate(numSchema, { port: '4040' })).toThrow(PrincipiaError)
119
+ expect(() => validate(numSchema, { port: '4040' })).toThrow(EmpyriaError)
120
120
  })
121
121
 
122
122
  test('options are forwarded to the underlying Validator (coerceTypes)', () => {
@@ -1,6 +1,6 @@
1
1
  import { describe, test, expect } from 'bun:test'
2
2
  import { generateCodogram, CODOGRAM_LIST, CODOGRAMS } from '../lib/Codogram.js'
3
- import { PrincipiaError } from '../lib/Errors.js'
3
+ import { EmpyriaError } from '../lib/Errors.js'
4
4
 
5
5
  describe('generateCodogram', () => {
6
6
  test('PIN: numeric within the default digit range', () => {
@@ -29,7 +29,7 @@ describe('generateCodogram', () => {
29
29
  })
30
30
 
31
31
  test('throws for an unrecognised type', () => {
32
- expect(() => generateCodogram('nonsense')).toThrow(PrincipiaError)
32
+ expect(() => generateCodogram('nonsense')).toThrow(EmpyriaError)
33
33
  })
34
34
  })
35
35
 
package/test/Env.test.js CHANGED
@@ -6,13 +6,13 @@ describe('createEnv', () => {
6
6
  const schema = createEnv({ CUSTOM_FLAG: { type: 'boolean' } })
7
7
  expect(schema.type).toBe('object')
8
8
  expect(schema.properties.NODE_ENV.default).toBe('local')
9
- expect(schema.properties.PRINCIPIA_ID_LENGTH.default).toBe(32)
9
+ expect(schema.properties.EMPYRIA_ID_LENGTH.default).toBe(32)
10
10
  expect(schema.properties.CUSTOM_FLAG).toEqual({ type: 'boolean' })
11
11
  expect(schema.required).toContain('CUSTOM_FLAG')
12
12
  })
13
13
 
14
14
  test('does not include connector-only settings', () => {
15
15
  const schema = createEnv()
16
- expect(schema.properties.PRINCIPIA_MONGO_URI).toBeUndefined()
16
+ expect(schema.properties.EMPYRIA_MONGO_URI).toBeUndefined()
17
17
  })
18
18
  })
@@ -1,9 +1,9 @@
1
1
  import { describe, test, expect } from 'bun:test'
2
- import { PrincipiaError, ErrorCreator, BaseErrors } from '../lib/Errors.js'
2
+ import { EmpyriaError, ErrorCreator, BaseErrors } from '../lib/Errors.js'
3
3
 
4
- describe('PrincipiaError', () => {
4
+ describe('EmpyriaError', () => {
5
5
  test('carries message, errorName, and errorCode', () => {
6
- const err = new PrincipiaError('Something broke', 'SomeError', 12345)
6
+ const err = new EmpyriaError('Something broke', 'SomeError', 12345)
7
7
  expect(err).toBeInstanceOf(Error)
8
8
  expect(err.message).toBe('Something broke')
9
9
  expect(err.errorName).toBe('SomeError')
@@ -20,7 +20,7 @@ describe('ErrorCreator', () => {
20
20
  message: 'Value {value} is bad',
21
21
  })
22
22
  const err = factory({ value: 42 })
23
- expect(err).toBeInstanceOf(PrincipiaError)
23
+ expect(err).toBeInstanceOf(EmpyriaError)
24
24
  expect(err.message).toBe('Value 42 is bad')
25
25
  expect(err.errorName).toBe('Custom')
26
26
  expect(err.errorCode).toBe(1)
@@ -1,13 +1,13 @@
1
1
  import { describe, test, expect } from 'bun:test'
2
2
  import {
3
3
  MOLECULER_SERVICE_ROLE,
4
- PRINCIPIA_FEDERATION_ID,
4
+ EMPYRIA_FEDERATION_ID,
5
5
  moleculerMeta,
6
- moleculerPrincipiaMeta,
6
+ moleculerEmpyriaMeta,
7
7
  workflowName,
8
8
  workflowId,
9
9
  identifyWorkflow,
10
- PrincipiaError,
10
+ EmpyriaError,
11
11
  } from '../index.js'
12
12
 
13
13
  const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
@@ -30,19 +30,19 @@ describe('moleculerMeta', () => {
30
30
  })
31
31
  })
32
32
 
33
- describe('moleculerPrincipiaMeta', () => {
33
+ describe('moleculerEmpyriaMeta', () => {
34
34
  test('uses the federation ID as actor/federation and generates missing IDs', () => {
35
35
  // Regression test: this used to call an unimported `uuid()` and throw ReferenceError.
36
- const meta = moleculerPrincipiaMeta({ tokenKey: 'key' })
37
- expect(meta.user.actor).toBe(PRINCIPIA_FEDERATION_ID)
38
- expect(meta.user.federation).toBe(PRINCIPIA_FEDERATION_ID)
36
+ const meta = moleculerEmpyriaMeta({ tokenKey: 'key' })
37
+ expect(meta.user.actor).toBe(EMPYRIA_FEDERATION_ID)
38
+ expect(meta.user.federation).toBe(EMPYRIA_FEDERATION_ID)
39
39
  expect(meta.user.role).toBe(MOLECULER_SERVICE_ROLE)
40
40
  expect(meta.user.flowID).toMatch(UUID_RE)
41
41
  expect(meta.user.processID).toMatch(UUID_RE)
42
42
  })
43
43
 
44
44
  test('keeps explicitly provided flowID/processID', () => {
45
- const meta = moleculerPrincipiaMeta({ flowID: 'f1', processID: 'p1', tokenKey: 'key' })
45
+ const meta = moleculerEmpyriaMeta({ flowID: 'f1', processID: 'p1', tokenKey: 'key' })
46
46
  expect(meta.user.flowID).toBe('f1')
47
47
  expect(meta.user.processID).toBe('p1')
48
48
  })
@@ -69,8 +69,8 @@ describe('identifyWorkflow', () => {
69
69
  expect(identifyWorkflow(id)).toEqual({ service: 'SVC', handler: 'H' })
70
70
  })
71
71
 
72
- test('throws a PrincipiaError for a malformed ID', () => {
73
- expect(() => identifyWorkflow('too:short')).toThrow(PrincipiaError)
74
- expect(() => identifyWorkflow(undefined)).toThrow(PrincipiaError)
72
+ test('throws a EmpyriaError for a malformed ID', () => {
73
+ expect(() => identifyWorkflow('too:short')).toThrow(EmpyriaError)
74
+ expect(() => identifyWorkflow(undefined)).toThrow(EmpyriaError)
75
75
  })
76
76
  })