Yamato DaiwaE(CMA)S(cript) extensions

RawObjectDataProcessorのデモ

引数externalDataの値が、 TypeScriptに依るチェックが及ばない 外部データソースから取得されたものだとする。

例えば、次の様なシナリオがよくある。

  • クライアント・—サーバーモデルに於けるクライアント側からのデータ取得
  • 逆に、クライアント—・サーバーモデルに於けるサーバー側からのデータ取得
  • データベースからのデート取得
  • ファイル(JSONYAML等)からの読み取り

受け取るデータはSampleTypeであると期待されているが、実行時に 実際どの様なデータに成るかはコード記述段階では不明。 従って此の引数SampleTypeではなくunknownに成っている。

此の為、externalData as SampleTypeの様にを強制するのは 危険。 とはいえTypeScriptの自然上、最終的にはそうせざるを得ない ( 問題の概観を参照)が、を強制する上で何れかの安全性対策が必用、即ち妥当性確認

此の課題をRawObjectDataProcessorで解決するには、妥当データ仕様を定義する事が必要。 此れは本質的上特定のデータに該当しているメタデータと成り、とりわけ想定される各プロパティ、 それらの必須性や其の他の制約を記述したオブジェクト。 デモの為、期待されるプロパティの指定に加え、文字列プロパティの最大文字数 や許可される値の候補といった制約も幾つか加えてある。 上記の様な検証は実戦に於いて需要が高い為、此の例にとって余計な分に成らない。

妥当データ仕様を定義したら、其の仕様と、依然としてunknownのままの 生データを併せて、RawObjectDataProcessorstaticメソッド processパラメータとして渡す事。

processメソッドの戻り値は、次の様に定義されたに成る。

此処での大事な事は、先ずisRawDataInvalidプロパティfalse値を持っているとTypeScriptに証明しないからには、 processedDataプロパティにアクセス不可能という事だ。

isRawDataInvalidプロパティtrueになっている 場合にprocessedDataにはアクセス不可能だ。 そもそも其の値が存在しない事が当然な理由で、代わりに実データと期待値の不一致を全て記述した検証エラーメッセージの配列にアクセス出来る。 これらの検証エラーをどうすれば良いか、要件次第になっているが、通常はユーザーへの通知やエラー投げ。

上の例の通り、RawObjectDataProcessorは検証エラーメッセージを整形する為の静的メソッド も提供している。 例えば次の入力でonDataRetrievedを呼び出すと、

Node.jsは下記ログを出力する。

InvalidExternalDataError: The data "N External Data" does not match with expected.
─── Error No. 1 ────────────────────────────────────────────────────────────────
Expected and Actual Numbers Set Mismatch [ VALIDATION_ERRORS_MESSAGES-NUMERIC_VALUE_IS_NOT_BELONG_TO_EXPECTED_NUMBERS_SET ]

● Property / Element: foo
Contrary to expectations, this numeric value is not member of "positive integer or zero"
See documentation for details: https://ee.yamato-daiwa.com/CoreLibrary/Functionality/RawObjectDataProcessor/Children/06-ValidationIssues/RawObjectDataProcessor-ValidationIssues.english.html#VALIDATION_ERRORS_MESSAGES-NUMERIC_VALUE_IS_NOT_BELONG_TO_EXPECTED_NUMBERS_SET

● Property / Element Specification:
{
  type: "number",
  isUndefinedForbidden: true,
  isNullForbidden: true,
  numbersSet: "POSITIVE_INTEGER_OR_ZERO",
  isNaN_Forbidden: true
}
● Actual Value: -4

─── Error No. 2 ────────────────────────────────────────────────────────────────
Minimal Characters Count Fall Short [ VALIDATION_ERRORS_MESSAGES-CHARACTERS_COUNT_IS_LESS_THAN_REQUIRED ]

● Property / Element: bar
This string has 3 characters while at least 5 required.
See documentation for details: https://ee.yamato-daiwa.com/CoreLibrary/Functionality/RawObjectDataProcessor/Children/06-ValidationIssues/RawObjectDataProcessor-ValidationIssues.english.html#VALIDATION_ERRORS_MESSAGES-CHARACTERS_COUNT_IS_LESS_THAN_REQUIRED

● Property / Element Specification:
{
  type: "string",
  isUndefinedForbidden: true,
  isNullForbidden: true,
  minimalCharactersCount: 5
}
● Actual Value: "abc"

─── Error No. 3 ────────────────────────────────────────────────────────────────
Forbidden Undefined Value [ VALIDATION_ERRORS_MESSAGES-FORBIDDEN_UNDEFINED_VALUE ]

● Property / Element: baz
This property/element is not defined or have explicit `undefined` value what has been explicitly forbidden.
See documentation for details: https://ee.yamato-daiwa.com/CoreLibrary/Functionality/RawObjectDataProcessor/Children/06-ValidationIssues/RawObjectDataProcessor-ValidationIssues.english.html#VALIDATION_ERRORS_MESSAGES-FORBIDDEN_UNDEFINED_VALUE

● Property / Element Specification:
{
  type: "boolean",
  isUndefinedForbidden: true,
  isNullForbidden: true
}
● Actual Value: undefined

─── Error No. 4 ────────────────────────────────────────────────────────────────
Forbidden Undefined Value [ VALIDATION_ERRORS_MESSAGES-FORBIDDEN_UNDEFINED_VALUE ]

● Property / Element: fuga
This property/element is not defined or have explicit `undefined` value what has been explicitly forbidden.
See documentation for details: https://ee.yamato-daiwa.com/CoreLibrary/Functionality/RawObjectDataProcessor/Children/06-ValidationIssues/RawObjectDataProcessor-ValidationIssues.english.html#VALIDATION_ERRORS_MESSAGES-FORBIDDEN_UNDEFINED_VALUE

● Property / Element Specification:
{
  type: "number",
  isUndefinedForbidden: true,
  isNullForbidden: false,
  numbersSet: "POSITIVE_INTEGER_OR_ZERO",
  isNaN_Forbidden: true
}
● Actual Value: undefined

─── Error No. 5 ────────────────────────────────────────────────────────────────
Minimal Value Fall Short [ VALIDATION_ERRORS_MESSAGES-NUMERIC_VALUE_IS_SMALLER_THAN_REQUIRED_MINIMUM ]

● Property / Element: quux.alpha
This value is smaller than required minimal value 3.
See documentation for details: https://ee.yamato-daiwa.com/CoreLibrary/Functionality/RawObjectDataProcessor/Children/06-ValidationIssues/RawObjectDataProcessor-ValidationIssues.english.html#VALIDATION_ERRORS_MESSAGES-NUMERIC_VALUE_IS_SMALLER_THAN_REQUIRED_MINIMUM

● Property / Element Specification:
{
  type: "number",
  isUndefinedForbidden: true,
  isNullForbidden: true,
  numbersSet: "ANY_INTEGER",
  isNaN_Forbidden: true,
  minimalValue: 3
}
● Actual Value: 2

─── Error No. 6 ────────────────────────────────────────────────────────────────
Disallowed Alternative of Value [ VALIDATION_ERRORS_MESSAGES-VALUE_IS_NOT_AMONG_ALLOWED_ALTERNATIVES ]

● Property / Element: quux.bravo
This value is not among following allowed alternatives:
  ○ PLATINUM
  ○ GOLD
  ○ SILVER
See documentation for details: https://ee.yamato-daiwa.com/CoreLibrary/Functionality/RawObjectDataProcessor/Children/06-ValidationIssues/RawObjectDataProcessor-ValidationIssues.english.html#VALIDATION_ERRORS_MESSAGES-VALUE_IS_NOT_AMONG_ALLOWED_ALTERNATIVES

● Property / Element Specification:
{
  type: "string",
  isUndefinedForbidden: true,
  isNullForbidden: true,
  minimalCharactersCount: 5,
  allowedAlternatives: [
    "PLATINUM",
    "GOLD",
    "SILVER"
  ]
}
● Actual Value: "BRONZE"
    at onDataRetrieved (D:\Demo.ts:87:11)
    at <anonymous> (D:\Demo.ts:99:1)
    at Object.<anonymous> (D:\Demo.ts:106:2)
    at Module._compile (node:internal/modules/cjs/loader:1730:14)
    at Object.transformer (C:\Users\I\AppData\Roaming\npm\node_modules\tsx\dist\register-DpmFHar1.cjs:2:1186)
    at Module.load (node:internal/modules/cjs/loader:1465:32)
    at Function._load (node:internal/modules/cjs/loader:1282:12)
    at TracingChannel.traceSync (node:diagnostics_channel:322:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:235:24)
    at cjsLoader (node:internal/modules/esm/translators:266:5)

Node.js v22.15.0

isRawDataInvalidfalseの場合、 processedDataプロパティにアクセスして利用可能。

上記の例の様な固定スキーマのオブジェクト以外にも、RawObjectDataProcessorは他の種類の オブジェクトも検証出来る。

  • 連想配列固定スキーマのオブジェクトと異なり、キー・値組数が 規制は無いが、値は共通の規則に従わなければいけない。
  • 指数配列
  • タプル指数配列と異なり、要素数と順序が固定で、 更に要素に個別の制約を設定可能。

何故此のクラス名がRawObjectDataValidator(「生オブジェクト型データのバリデータ」)ではなく、 RawObjectDataProcessor(「生オブジェクト型データのプロセッサ」)になっているだろうか。 理由は、此のクラスが妥当性確認を行っているだけでなく、必用に応じて変換(例えばキーの名前の変更や値の変更)も可能という事。 今後詳細を当説明書に解説。