@twin.org/core 0.0.3-next.13 → 0.0.3-next.15
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/es/types/urn.js +1 -2
- package/dist/es/types/urn.js.map +1 -1
- package/docs/changelog.md +34 -0
- package/package.json +2 -2
package/dist/es/types/urn.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { GuardError } from "../errors/guardError.js";
|
|
2
2
|
import { RandomHelper } from "../helpers/randomHelper.js";
|
|
3
|
-
import { Converter } from "../utils/converter.js";
|
|
4
3
|
import { Guards } from "../utils/guards.js";
|
|
5
4
|
import { Is } from "../utils/is.js";
|
|
6
5
|
/**
|
|
@@ -40,7 +39,7 @@ export class Urn {
|
|
|
40
39
|
* @returns A new Id in URN format.
|
|
41
40
|
*/
|
|
42
41
|
static generateRandom(namespace) {
|
|
43
|
-
return new Urn(namespace,
|
|
42
|
+
return new Urn(namespace, RandomHelper.generateUuidV7("compact"));
|
|
44
43
|
}
|
|
45
44
|
/**
|
|
46
45
|
* Does the provided urn match the namespace.
|
package/dist/es/types/urn.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"urn.js","sourceRoot":"","sources":["../../../src/types/urn.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAEpC;;GAEG;AACH,MAAM,OAAO,GAAG;IACf;;OAEG;IACI,MAAM,CAAU,UAAU,SAAyB;IAE1D;;;OAGG;IACc,SAAS,CAAW;IAErC;;;;OAIG;IACH,YAAY,mBAA2B,EAAE,iBAAoC;QAC5E,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,yBAA+B,mBAAmB,CAAC,CAAC;QAErF,oCAAoC;QACpC,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAEzD,IAAI,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACjC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,uBAA6B,iBAAiB,CAAC,CAAC;YAChF,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACP,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,uBAA6B,iBAAiB,CAAC,CAAC;YACjF,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACxE,CAAC;IACF,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,cAAc,CAAC,SAAiB;QAC7C,OAAO,IAAI,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,YAAY,CAAC,GAAW,EAAE,SAAiB;QACxD,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,KAAK,CAAC;QACd,CAAC;QACD,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC;YACrC,OAAO,GAAG,KAAK,SAAS,CAAC;QAC1B,CAAC;QAED,OAAO,GAAG,CAAC,UAAU,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC;IACxC,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,aAAa,CAAC,GAAY;QACvC,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO;QACR,CAAC;QAED,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE7B,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC;YACxB,KAAK,CAAC,KAAK,EAAE,CAAC;QACf,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO;QACR,CAAC;QAED,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,OAAO;QACR,CAAC;QAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnD,OAAO;YACR,CAAC;QACF,CAAC;QAED,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,eAAe,CAAC,GAAW;QACxC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE7B,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC;YACxB,KAAK,CAAC,KAAK,EAAE,CAAC;QACf,CAAC;QAED,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,SAAS,CAAC,GAAY;QACnC,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5B,OAAO,GAAG,CAAC;YACZ,CAAC;YACD,OAAO,OAAO,GAAG,EAAE,CAAC;QACrB,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,KAAK,CAAC,MAAc,EAAE,QAAgB,EAAE,KAAc;QACnE,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAE5C,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAExC,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC5D,CAAC;IACF,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,QAAQ,CACrB,QAAgB,EAChB,KAAc,EACd,QAA8B,EAC9B,iBAA0B;QAE1B,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,QAAQ,CAAC,IAAI,CAAC;gBACb,QAAQ;gBACR,MAAM,EAAE,uBAAuB;gBAC/B,UAAU,EAAE,EAAE,SAAS,EAAE,iBAAiB,IAAI,6BAA6B,EAAE,KAAK,EAAE;aACpF,CAAC,CAAC;YAEH,OAAO,KAAK,CAAC;QACd,CAAC;QAED,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAExC,IAAI,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC;gBACb,QAAQ;gBACR,MAAM,EAAE,kBAAkB;gBAC1B,UAAU,EAAE,EAAE,SAAS,EAAE,iBAAiB,IAAI,6BAA6B,EAAE,KAAK,EAAE;aACpF,CAAC,CAAC;YAEH,OAAO,KAAK,CAAC;QACd,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,aAAqB,CAAC;QAClC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC;IAED;;;OAGG;IACI,mBAAmB;QACzB,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACI,eAAe;QACrB,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,CAAC;IAED;;;;OAIG;IACI,sBAAsB,CAAC,aAAqB,CAAC;QACnD,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,CAAC;IAED;;;;OAIG;IACI,iBAAiB,CAAC,aAAqB,CAAC;QAC9C,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACxF,CAAC;IAED;;;;OAIG;IACI,QAAQ,CAAC,aAAsB,IAAI;QACzC,OAAO,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IAClF,CAAC;IAED;;;;;OAKG;IACK,WAAW,CAAC,GAAW;QAC9B,OAAO,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { nameof } from \"@twin.org/nameof\";\nimport { GuardError } from \"../errors/guardError.js\";\nimport { RandomHelper } from \"../helpers/randomHelper.js\";\nimport type { IValidationFailure } from \"../models/IValidationFailure.js\";\nimport { Converter } from \"../utils/converter.js\";\nimport { Guards } from \"../utils/guards.js\";\nimport { Is } from \"../utils/is.js\";\n\n/**\n * Class to help with urns.\n */\nexport class Urn {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<Urn>();\n\n\t/**\n\t * The specific part of the namespace.\n\t * @internal\n\t */\n\tprivate readonly _urnParts: string[];\n\n\t/**\n\t * Create a new instance of Urn.\n\t * @param namespaceIdentifier The identifier for the namespace.\n\t * @param namespaceSpecific The specific part of the namespace.\n\t */\n\tconstructor(namespaceIdentifier: string, namespaceSpecific: string | string[]) {\n\t\tGuards.stringValue(Urn.CLASS_NAME, nameof(namespaceIdentifier), namespaceIdentifier);\n\n\t\t// Strip leading and trailing colons\n\t\tthis._urnParts = [this.stripColons(namespaceIdentifier)];\n\n\t\tif (Is.array(namespaceSpecific)) {\n\t\t\tGuards.arrayValue(Urn.CLASS_NAME, nameof(namespaceSpecific), namespaceSpecific);\n\t\t\tthis._urnParts.push(...namespaceSpecific);\n\t\t} else {\n\t\t\tGuards.stringValue(Urn.CLASS_NAME, nameof(namespaceSpecific), namespaceSpecific);\n\t\t\tthis._urnParts.push(...this.stripColons(namespaceSpecific).split(\":\"));\n\t\t}\n\t}\n\n\t/**\n\t * Generate a random identifier with 32 byte id.\n\t * @param namespace The prefix for the urn.\n\t * @returns A new Id in URN format.\n\t */\n\tpublic static generateRandom(namespace: string): Urn {\n\t\treturn new Urn(namespace, Converter.bytesToHex(RandomHelper.generate(32)));\n\t}\n\n\t/**\n\t * Does the provided urn match the namespace.\n\t * @param urn The urn to check.\n\t * @param namespace The namespace to match.\n\t * @returns True if the namespace matches.\n\t */\n\tpublic static hasNamespace(urn: string, namespace: string): boolean {\n\t\tif (!Is.stringValue(urn)) {\n\t\t\treturn false;\n\t\t}\n\t\tif (urn.startsWith(\"urn:\")) {\n\t\t\turn = urn.slice(4);\n\t\t}\n\n\t\tif (urn.length === namespace.length) {\n\t\t\treturn urn === namespace;\n\t\t}\n\n\t\treturn urn.startsWith(`${namespace}:`);\n\t}\n\n\t/**\n\t * Try and parse a string into the urn parts.\n\t * @param urn The urn to parse.\n\t * @returns The formatted urn or undefined if the value is not a urn.\n\t */\n\tpublic static tryParseExact(urn: unknown): Urn | undefined {\n\t\tif (!Is.stringValue(urn)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst parts = urn.split(\":\");\n\n\t\tif (parts[0] === \"urn\") {\n\t\t\tparts.shift();\n\t\t}\n\n\t\tif (parts.length < 2) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!/[\\da-z][\\da-z-]{0,31}/.test(parts[0])) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (let i = 1; i < parts.length; i++) {\n\t\t\tif (!/[\\d!#$%'()*+,./:;=?@_a-z-]+/.test(parts[i])) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\treturn new Urn(parts[0], parts.slice(1));\n\t}\n\n\t/**\n\t * Construct a urn from a string that has already been validated.\n\t * @param urn The urn to parse.\n\t * @returns The formatted urn.\n\t */\n\tpublic static fromValidString(urn: string): Urn {\n\t\tconst parts = urn.split(\":\");\n\n\t\tif (parts[0] === \"urn\") {\n\t\t\tparts.shift();\n\t\t}\n\n\t\treturn new Urn(parts[0], parts.slice(1));\n\t}\n\n\t/**\n\t * Add a urn: prefix if there isn't one already.\n\t * @param urn The urn string to add a prefix to.\n\t * @returns The urn with a prefix.\n\t */\n\tpublic static addPrefix(urn: unknown): string | undefined {\n\t\tif (Is.stringValue(urn)) {\n\t\t\tif (urn.startsWith(\"urn:\")) {\n\t\t\t\treturn urn;\n\t\t\t}\n\t\t\treturn `urn:${urn}`;\n\t\t}\n\t}\n\n\t/**\n\t * Parse a string into the urn parts.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The urn to parse.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static guard(source: string, property: string, value: unknown): asserts value is string {\n\t\tGuards.stringValue(source, property, value);\n\n\t\tconst result = Urn.tryParseExact(value);\n\n\t\tif (!result) {\n\t\t\tthrow new GuardError(source, \"guard.urn\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Validate a string as a Urn.\n\t * @param property Throw an exception if the urn property is invalid.\n\t * @param value The urn to parse.\n\t * @param failures The list of failures to add to.\n\t * @param fieldNameResource The optional human readable name for the field as an i18 resource.\n\t * @returns The formatted urn.\n\t */\n\tpublic static validate(\n\t\tproperty: string,\n\t\tvalue: unknown,\n\t\tfailures: IValidationFailure[],\n\t\tfieldNameResource?: string\n\t): value is string {\n\t\tif (!Is.stringValue(value)) {\n\t\t\tfailures.push({\n\t\t\t\tproperty,\n\t\t\t\treason: \"validation.beNotEmpty\",\n\t\t\t\tproperties: { fieldName: fieldNameResource ?? \"validation.defaultFieldName\", value }\n\t\t\t});\n\n\t\t\treturn false;\n\t\t}\n\n\t\tconst result = Urn.tryParseExact(value);\n\n\t\tif (Is.undefined(result)) {\n\t\t\tfailures.push({\n\t\t\t\tproperty,\n\t\t\t\treason: \"validation.beUrn\",\n\t\t\t\tproperties: { fieldName: fieldNameResource ?? \"validation.defaultFieldName\", value }\n\t\t\t});\n\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Get the parts.\n\t * @param startIndex The index to start from, defaults to 0.\n\t * @returns The parts.\n\t */\n\tpublic parts(startIndex: number = 0): string[] {\n\t\treturn this._urnParts.slice(startIndex);\n\t}\n\n\t/**\n\t * Get the namespace identifier.\n\t * @returns The namespace identifier.\n\t */\n\tpublic namespaceIdentifier(): string {\n\t\treturn this._urnParts[0];\n\t}\n\n\t/**\n\t * Get the namespace method, the first component after the identifier.\n\t * @returns The namespace method.\n\t */\n\tpublic namespaceMethod(): string {\n\t\treturn this._urnParts.length > 1 ? this._urnParts[1] : \"\";\n\t}\n\n\t/**\n\t * Get the namespace specific parts.\n\t * @param startIndex The index to start from, defaults to 0.\n\t * @returns The namespace specific parts.\n\t */\n\tpublic namespaceSpecificParts(startIndex: number = 0): string[] {\n\t\treturn this._urnParts.length > 1 ? this._urnParts.slice(startIndex + 1) : [];\n\t}\n\n\t/**\n\t * Get the namespace specific.\n\t * @param startIndex The index to start from, defaults to 0.\n\t * @returns The namespace specific.\n\t */\n\tpublic namespaceSpecific(startIndex: number = 0): string {\n\t\treturn this._urnParts.length > 1 ? this._urnParts.slice(startIndex + 1).join(\":\") : \"\";\n\t}\n\n\t/**\n\t * Convert the parts in to a full string.\n\t * @param omitPrefix Omit the urn: prefix from the string.\n\t * @returns The formatted urn.\n\t */\n\tpublic toString(omitPrefix: boolean = true): string {\n\t\treturn omitPrefix ? this._urnParts.join(\":\") : `urn:${this._urnParts.join(\":\")}`;\n\t}\n\n\t/**\n\t * Strip the leading and trailing colons from a string.\n\t * @param val The value to strip.\n\t * @returns The stripped string.\n\t * @internal\n\t */\n\tprivate stripColons(val: string): string {\n\t\treturn val.replace(/^:?(.*?):?$/, \"$1\");\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"urn.js","sourceRoot":"","sources":["../../../src/types/urn.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { nameof } from \"@twin.org/nameof\";\nimport { GuardError } from \"../errors/guardError.js\";\nimport { RandomHelper } from \"../helpers/randomHelper.js\";\nimport type { IValidationFailure } from \"../models/IValidationFailure.js\";\nimport { Guards } from \"../utils/guards.js\";\nimport { Is } from \"../utils/is.js\";\n\n/**\n * Class to help with urns.\n */\nexport class Urn {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<Urn>();\n\n\t/**\n\t * The specific part of the namespace.\n\t * @internal\n\t */\n\tprivate readonly _urnParts: string[];\n\n\t/**\n\t * Create a new instance of Urn.\n\t * @param namespaceIdentifier The identifier for the namespace.\n\t * @param namespaceSpecific The specific part of the namespace.\n\t */\n\tconstructor(namespaceIdentifier: string, namespaceSpecific: string | string[]) {\n\t\tGuards.stringValue(Urn.CLASS_NAME, nameof(namespaceIdentifier), namespaceIdentifier);\n\n\t\t// Strip leading and trailing colons\n\t\tthis._urnParts = [this.stripColons(namespaceIdentifier)];\n\n\t\tif (Is.array(namespaceSpecific)) {\n\t\t\tGuards.arrayValue(Urn.CLASS_NAME, nameof(namespaceSpecific), namespaceSpecific);\n\t\t\tthis._urnParts.push(...namespaceSpecific);\n\t\t} else {\n\t\t\tGuards.stringValue(Urn.CLASS_NAME, nameof(namespaceSpecific), namespaceSpecific);\n\t\t\tthis._urnParts.push(...this.stripColons(namespaceSpecific).split(\":\"));\n\t\t}\n\t}\n\n\t/**\n\t * Generate a random identifier with 32 byte id.\n\t * @param namespace The prefix for the urn.\n\t * @returns A new Id in URN format.\n\t */\n\tpublic static generateRandom(namespace: string): Urn {\n\t\treturn new Urn(namespace, RandomHelper.generateUuidV7(\"compact\"));\n\t}\n\n\t/**\n\t * Does the provided urn match the namespace.\n\t * @param urn The urn to check.\n\t * @param namespace The namespace to match.\n\t * @returns True if the namespace matches.\n\t */\n\tpublic static hasNamespace(urn: string, namespace: string): boolean {\n\t\tif (!Is.stringValue(urn)) {\n\t\t\treturn false;\n\t\t}\n\t\tif (urn.startsWith(\"urn:\")) {\n\t\t\turn = urn.slice(4);\n\t\t}\n\n\t\tif (urn.length === namespace.length) {\n\t\t\treturn urn === namespace;\n\t\t}\n\n\t\treturn urn.startsWith(`${namespace}:`);\n\t}\n\n\t/**\n\t * Try and parse a string into the urn parts.\n\t * @param urn The urn to parse.\n\t * @returns The formatted urn or undefined if the value is not a urn.\n\t */\n\tpublic static tryParseExact(urn: unknown): Urn | undefined {\n\t\tif (!Is.stringValue(urn)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst parts = urn.split(\":\");\n\n\t\tif (parts[0] === \"urn\") {\n\t\t\tparts.shift();\n\t\t}\n\n\t\tif (parts.length < 2) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!/[\\da-z][\\da-z-]{0,31}/.test(parts[0])) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (let i = 1; i < parts.length; i++) {\n\t\t\tif (!/[\\d!#$%'()*+,./:;=?@_a-z-]+/.test(parts[i])) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\treturn new Urn(parts[0], parts.slice(1));\n\t}\n\n\t/**\n\t * Construct a urn from a string that has already been validated.\n\t * @param urn The urn to parse.\n\t * @returns The formatted urn.\n\t */\n\tpublic static fromValidString(urn: string): Urn {\n\t\tconst parts = urn.split(\":\");\n\n\t\tif (parts[0] === \"urn\") {\n\t\t\tparts.shift();\n\t\t}\n\n\t\treturn new Urn(parts[0], parts.slice(1));\n\t}\n\n\t/**\n\t * Add a urn: prefix if there isn't one already.\n\t * @param urn The urn string to add a prefix to.\n\t * @returns The urn with a prefix.\n\t */\n\tpublic static addPrefix(urn: unknown): string | undefined {\n\t\tif (Is.stringValue(urn)) {\n\t\t\tif (urn.startsWith(\"urn:\")) {\n\t\t\t\treturn urn;\n\t\t\t}\n\t\t\treturn `urn:${urn}`;\n\t\t}\n\t}\n\n\t/**\n\t * Parse a string into the urn parts.\n\t * @param source The source of the error.\n\t * @param property The name of the property.\n\t * @param value The urn to parse.\n\t * @throws GuardError If the value does not match the assertion.\n\t */\n\tpublic static guard(source: string, property: string, value: unknown): asserts value is string {\n\t\tGuards.stringValue(source, property, value);\n\n\t\tconst result = Urn.tryParseExact(value);\n\n\t\tif (!result) {\n\t\t\tthrow new GuardError(source, \"guard.urn\", property, value);\n\t\t}\n\t}\n\n\t/**\n\t * Validate a string as a Urn.\n\t * @param property Throw an exception if the urn property is invalid.\n\t * @param value The urn to parse.\n\t * @param failures The list of failures to add to.\n\t * @param fieldNameResource The optional human readable name for the field as an i18 resource.\n\t * @returns The formatted urn.\n\t */\n\tpublic static validate(\n\t\tproperty: string,\n\t\tvalue: unknown,\n\t\tfailures: IValidationFailure[],\n\t\tfieldNameResource?: string\n\t): value is string {\n\t\tif (!Is.stringValue(value)) {\n\t\t\tfailures.push({\n\t\t\t\tproperty,\n\t\t\t\treason: \"validation.beNotEmpty\",\n\t\t\t\tproperties: { fieldName: fieldNameResource ?? \"validation.defaultFieldName\", value }\n\t\t\t});\n\n\t\t\treturn false;\n\t\t}\n\n\t\tconst result = Urn.tryParseExact(value);\n\n\t\tif (Is.undefined(result)) {\n\t\t\tfailures.push({\n\t\t\t\tproperty,\n\t\t\t\treason: \"validation.beUrn\",\n\t\t\t\tproperties: { fieldName: fieldNameResource ?? \"validation.defaultFieldName\", value }\n\t\t\t});\n\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Get the parts.\n\t * @param startIndex The index to start from, defaults to 0.\n\t * @returns The parts.\n\t */\n\tpublic parts(startIndex: number = 0): string[] {\n\t\treturn this._urnParts.slice(startIndex);\n\t}\n\n\t/**\n\t * Get the namespace identifier.\n\t * @returns The namespace identifier.\n\t */\n\tpublic namespaceIdentifier(): string {\n\t\treturn this._urnParts[0];\n\t}\n\n\t/**\n\t * Get the namespace method, the first component after the identifier.\n\t * @returns The namespace method.\n\t */\n\tpublic namespaceMethod(): string {\n\t\treturn this._urnParts.length > 1 ? this._urnParts[1] : \"\";\n\t}\n\n\t/**\n\t * Get the namespace specific parts.\n\t * @param startIndex The index to start from, defaults to 0.\n\t * @returns The namespace specific parts.\n\t */\n\tpublic namespaceSpecificParts(startIndex: number = 0): string[] {\n\t\treturn this._urnParts.length > 1 ? this._urnParts.slice(startIndex + 1) : [];\n\t}\n\n\t/**\n\t * Get the namespace specific.\n\t * @param startIndex The index to start from, defaults to 0.\n\t * @returns The namespace specific.\n\t */\n\tpublic namespaceSpecific(startIndex: number = 0): string {\n\t\treturn this._urnParts.length > 1 ? this._urnParts.slice(startIndex + 1).join(\":\") : \"\";\n\t}\n\n\t/**\n\t * Convert the parts in to a full string.\n\t * @param omitPrefix Omit the urn: prefix from the string.\n\t * @returns The formatted urn.\n\t */\n\tpublic toString(omitPrefix: boolean = true): string {\n\t\treturn omitPrefix ? this._urnParts.join(\":\") : `urn:${this._urnParts.join(\":\")}`;\n\t}\n\n\t/**\n\t * Strip the leading and trailing colons from a string.\n\t * @param val The value to strip.\n\t * @returns The stripped string.\n\t * @internal\n\t */\n\tprivate stripColons(val: string): string {\n\t\treturn val.replace(/^:?(.*?):?$/, \"$1\");\n\t}\n}\n"]}
|
package/docs/changelog.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# @twin.org/core - Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.3-next.15](https://github.com/twinfoundation/framework/compare/core-v0.0.3-next.14...core-v0.0.3-next.15) (2026-01-29)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* urn random switched to using uuidv7 ([6a29f8b](https://github.com/twinfoundation/framework/commit/6a29f8bd573d06992b7eaa027b1daf4c2a2e1e85))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* The following workspace dependencies were updated
|
|
14
|
+
* dependencies
|
|
15
|
+
* @twin.org/nameof bumped from 0.0.3-next.14 to 0.0.3-next.15
|
|
16
|
+
* devDependencies
|
|
17
|
+
* @twin.org/nameof-transformer bumped from 0.0.3-next.14 to 0.0.3-next.15
|
|
18
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.0.3-next.14 to 0.0.3-next.15
|
|
19
|
+
|
|
20
|
+
## [0.0.3-next.14](https://github.com/twinfoundation/framework/compare/core-v0.0.3-next.13...core-v0.0.3-next.14) (2026-01-22)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Miscellaneous Chores
|
|
24
|
+
|
|
25
|
+
* **core:** Synchronize repo versions
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Dependencies
|
|
29
|
+
|
|
30
|
+
* The following workspace dependencies were updated
|
|
31
|
+
* dependencies
|
|
32
|
+
* @twin.org/nameof bumped from 0.0.3-next.13 to 0.0.3-next.14
|
|
33
|
+
* devDependencies
|
|
34
|
+
* @twin.org/nameof-transformer bumped from 0.0.3-next.13 to 0.0.3-next.14
|
|
35
|
+
* @twin.org/nameof-vitest-plugin bumped from 0.0.3-next.13 to 0.0.3-next.14
|
|
36
|
+
|
|
3
37
|
## [0.0.3-next.13](https://github.com/twinfoundation/framework/compare/core-v0.0.3-next.12...core-v0.0.3-next.13) (2026-01-08)
|
|
4
38
|
|
|
5
39
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twin.org/core",
|
|
3
|
-
"version": "0.0.3-next.
|
|
3
|
+
"version": "0.0.3-next.15",
|
|
4
4
|
"description": "Helper methods/classes for data type checking/validation/guarding/error handling",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"node": ">=20.0.0"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@twin.org/nameof": "0.0.3-next.
|
|
17
|
+
"@twin.org/nameof": "0.0.3-next.15",
|
|
18
18
|
"intl-messageformat": "10.7.18",
|
|
19
19
|
"rfc6902": "5.1.2"
|
|
20
20
|
},
|