@kravc/schema 2.7.6 → 2.8.0-alpha.0

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 (170) hide show
  1. package/README.md +19 -14
  2. package/dist/CredentialFactory.d.ts +345 -0
  3. package/dist/CredentialFactory.d.ts.map +1 -0
  4. package/dist/CredentialFactory.js +381 -0
  5. package/dist/CredentialFactory.js.map +1 -0
  6. package/dist/Schema.d.ts +448 -0
  7. package/dist/Schema.d.ts.map +1 -0
  8. package/dist/Schema.js +506 -0
  9. package/dist/Schema.js.map +1 -0
  10. package/dist/ValidationError.d.ts +70 -0
  11. package/dist/ValidationError.d.ts.map +1 -0
  12. package/dist/ValidationError.js +78 -0
  13. package/dist/ValidationError.js.map +1 -0
  14. package/dist/Validator.d.ts +483 -0
  15. package/dist/Validator.d.ts.map +1 -0
  16. package/dist/Validator.js +570 -0
  17. package/dist/Validator.js.map +1 -0
  18. package/dist/helpers/JsonSchema.d.ts +99 -0
  19. package/dist/helpers/JsonSchema.d.ts.map +1 -0
  20. package/dist/helpers/JsonSchema.js +3 -0
  21. package/dist/helpers/JsonSchema.js.map +1 -0
  22. package/dist/helpers/cleanupAttributes.d.ts +34 -0
  23. package/dist/helpers/cleanupAttributes.d.ts.map +1 -0
  24. package/dist/helpers/cleanupAttributes.js +113 -0
  25. package/dist/helpers/cleanupAttributes.js.map +1 -0
  26. package/dist/helpers/cleanupNulls.d.ts +27 -0
  27. package/dist/helpers/cleanupNulls.d.ts.map +1 -0
  28. package/dist/helpers/cleanupNulls.js +96 -0
  29. package/dist/helpers/cleanupNulls.js.map +1 -0
  30. package/dist/helpers/getReferenceIds.d.ts +169 -0
  31. package/dist/helpers/getReferenceIds.d.ts.map +1 -0
  32. package/dist/helpers/getReferenceIds.js +241 -0
  33. package/dist/helpers/getReferenceIds.js.map +1 -0
  34. package/dist/helpers/got.d.ts +60 -0
  35. package/dist/helpers/got.d.ts.map +1 -0
  36. package/dist/helpers/got.js +72 -0
  37. package/dist/helpers/got.js.map +1 -0
  38. package/dist/helpers/mapObjectProperties.d.ts +150 -0
  39. package/dist/helpers/mapObjectProperties.d.ts.map +1 -0
  40. package/dist/helpers/mapObjectProperties.js +229 -0
  41. package/dist/helpers/mapObjectProperties.js.map +1 -0
  42. package/dist/helpers/normalizeAttributes.d.ts +213 -0
  43. package/dist/helpers/normalizeAttributes.d.ts.map +1 -0
  44. package/dist/helpers/normalizeAttributes.js +243 -0
  45. package/dist/helpers/normalizeAttributes.js.map +1 -0
  46. package/dist/helpers/normalizeProperties.d.ts +168 -0
  47. package/dist/helpers/normalizeProperties.d.ts.map +1 -0
  48. package/dist/helpers/normalizeProperties.js +223 -0
  49. package/dist/helpers/normalizeProperties.js.map +1 -0
  50. package/dist/helpers/normalizeRequired.d.ts +159 -0
  51. package/dist/helpers/normalizeRequired.d.ts.map +1 -0
  52. package/dist/helpers/normalizeRequired.js +206 -0
  53. package/dist/helpers/normalizeRequired.js.map +1 -0
  54. package/dist/helpers/normalizeType.d.ts +81 -0
  55. package/dist/helpers/normalizeType.d.ts.map +1 -0
  56. package/dist/helpers/normalizeType.js +210 -0
  57. package/dist/helpers/normalizeType.js.map +1 -0
  58. package/dist/helpers/nullifyEmptyValues.d.ts +139 -0
  59. package/dist/helpers/nullifyEmptyValues.d.ts.map +1 -0
  60. package/dist/helpers/nullifyEmptyValues.js +191 -0
  61. package/dist/helpers/nullifyEmptyValues.js.map +1 -0
  62. package/dist/helpers/removeRequiredAndDefault.d.ts +106 -0
  63. package/dist/helpers/removeRequiredAndDefault.d.ts.map +1 -0
  64. package/dist/helpers/removeRequiredAndDefault.js +138 -0
  65. package/dist/helpers/removeRequiredAndDefault.js.map +1 -0
  66. package/dist/helpers/validateId.d.ts +39 -0
  67. package/dist/helpers/validateId.d.ts.map +1 -0
  68. package/dist/helpers/validateId.js +51 -0
  69. package/dist/helpers/validateId.js.map +1 -0
  70. package/dist/index.d.ts +7 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +17 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/ld/documentLoader.d.ts +8 -0
  75. package/dist/ld/documentLoader.d.ts.map +1 -0
  76. package/dist/ld/documentLoader.js +24 -0
  77. package/dist/ld/documentLoader.js.map +1 -0
  78. package/dist/ld/getLinkedDataAttributeType.d.ts +10 -0
  79. package/dist/ld/getLinkedDataAttributeType.d.ts.map +1 -0
  80. package/dist/ld/getLinkedDataAttributeType.js +32 -0
  81. package/dist/ld/getLinkedDataAttributeType.js.map +1 -0
  82. package/dist/ld/getLinkedDataContext.d.ts +19 -0
  83. package/dist/ld/getLinkedDataContext.d.ts.map +1 -0
  84. package/dist/ld/getLinkedDataContext.js +50 -0
  85. package/dist/ld/getLinkedDataContext.js.map +1 -0
  86. package/eslint.config.mjs +32 -52
  87. package/examples/credentials/createAccountCredential.ts +27 -0
  88. package/examples/credentials/createMineSweeperScoreCredential.ts +115 -0
  89. package/examples/index.ts +7 -0
  90. package/examples/schemas/FavoriteItemSchema.ts +27 -0
  91. package/examples/{Preferences.yaml → schemas/Preferences.yaml} +2 -0
  92. package/examples/schemas/PreferencesSchema.ts +29 -0
  93. package/examples/schemas/ProfileSchema.ts +91 -0
  94. package/examples/schemas/Status.yaml +3 -0
  95. package/examples/schemas/StatusSchema.ts +12 -0
  96. package/jest.config.mjs +5 -0
  97. package/package.json +27 -20
  98. package/src/CredentialFactory.ts +392 -0
  99. package/src/Schema.ts +583 -0
  100. package/src/ValidationError.ts +90 -0
  101. package/src/Validator.ts +603 -0
  102. package/src/__tests__/CredentialFactory.test.ts +588 -0
  103. package/src/__tests__/Schema.test.ts +371 -0
  104. package/src/__tests__/ValidationError.test.ts +235 -0
  105. package/src/__tests__/Validator.test.ts +787 -0
  106. package/src/helpers/JsonSchema.ts +119 -0
  107. package/src/helpers/__tests__/cleanupAttributes.test.ts +943 -0
  108. package/src/helpers/__tests__/cleanupNulls.test.ts +772 -0
  109. package/src/helpers/__tests__/getReferenceIds.test.ts +975 -0
  110. package/src/helpers/__tests__/got.test.ts +193 -0
  111. package/src/helpers/__tests__/mapObjectProperties.test.ts +1126 -0
  112. package/src/helpers/__tests__/normalizeAttributes.test.ts +1435 -0
  113. package/src/helpers/__tests__/normalizeProperties.test.ts +727 -0
  114. package/src/helpers/__tests__/normalizeRequired.test.ts +669 -0
  115. package/src/helpers/__tests__/normalizeType.test.ts +772 -0
  116. package/src/helpers/__tests__/nullifyEmptyValues.test.ts +735 -0
  117. package/src/helpers/__tests__/removeRequiredAndDefault.test.ts +734 -0
  118. package/src/helpers/__tests__/validateId.test.ts +118 -0
  119. package/src/helpers/cleanupAttributes.ts +151 -0
  120. package/src/helpers/cleanupNulls.ts +106 -0
  121. package/src/helpers/getReferenceIds.ts +273 -0
  122. package/src/helpers/got.ts +73 -0
  123. package/src/helpers/mapObjectProperties.ts +272 -0
  124. package/src/helpers/normalizeAttributes.ts +247 -0
  125. package/src/helpers/normalizeProperties.ts +249 -0
  126. package/src/helpers/normalizeRequired.ts +233 -0
  127. package/src/helpers/normalizeType.ts +235 -0
  128. package/src/helpers/nullifyEmptyValues.ts +207 -0
  129. package/src/helpers/removeRequiredAndDefault.ts +151 -0
  130. package/src/helpers/validateId.ts +53 -0
  131. package/src/index.ts +13 -0
  132. package/src/ld/__tests__/documentLoader.test.ts +57 -0
  133. package/src/ld/__tests__/getLinkedDataAttributeType.test.ts +212 -0
  134. package/src/ld/__tests__/getLinkedDataContext.test.ts +378 -0
  135. package/src/ld/documentLoader.ts +28 -0
  136. package/src/ld/getLinkedDataAttributeType.ts +46 -0
  137. package/src/ld/getLinkedDataContext.ts +80 -0
  138. package/tsconfig.json +27 -0
  139. package/types/credentials-context.d.ts +14 -0
  140. package/types/security-context.d.ts +6 -0
  141. package/examples/Status.yaml +0 -3
  142. package/examples/createAccountCredential.js +0 -27
  143. package/examples/createMineSweeperScoreCredential.js +0 -63
  144. package/examples/index.js +0 -9
  145. package/src/CredentialFactory.js +0 -67
  146. package/src/CredentialFactory.spec.js +0 -131
  147. package/src/Schema.js +0 -104
  148. package/src/Schema.spec.js +0 -172
  149. package/src/ValidationError.js +0 -31
  150. package/src/Validator.js +0 -128
  151. package/src/Validator.spec.js +0 -355
  152. package/src/helpers/cleanupAttributes.js +0 -71
  153. package/src/helpers/cleanupNulls.js +0 -42
  154. package/src/helpers/getReferenceIds.js +0 -71
  155. package/src/helpers/mapObject.js +0 -65
  156. package/src/helpers/normalizeAttributes.js +0 -28
  157. package/src/helpers/normalizeProperties.js +0 -61
  158. package/src/helpers/normalizeRequired.js +0 -37
  159. package/src/helpers/normalizeType.js +0 -41
  160. package/src/helpers/nullifyEmptyValues.js +0 -57
  161. package/src/helpers/removeRequiredAndDefault.js +0 -30
  162. package/src/helpers/validateId.js +0 -19
  163. package/src/index.d.ts +0 -25
  164. package/src/index.js +0 -8
  165. package/src/ld/documentLoader.js +0 -25
  166. package/src/ld/documentLoader.spec.js +0 -12
  167. package/src/ld/getLinkedDataContext.js +0 -63
  168. package/src/ld/getLinkedDataType.js +0 -38
  169. /package/examples/{FavoriteItem.yaml → schemas/FavoriteItem.yaml} +0 -0
  170. /package/examples/{Profile.yaml → schemas/Profile.yaml} +0 -0
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const validator_1 = require("validator");
4
+ /**
5
+ * Validates that a value is a URL or a DID (Decentralized Identifier).
6
+ * Throws if the value is missing, null, undefined, or not a valid URL/DID.
7
+ *
8
+ * **Intent**
9
+ * Enforce that identifier-style parameters (schema IDs, credential IDs, subject
10
+ * references, etc.) are either resolvable URLs or W3C DIDs before they are used
11
+ * in Linked Data or verification flows. This prevents malformed or arbitrary
12
+ * strings from propagating into storage, APIs, or cryptographic operations.
13
+ *
14
+ * **Use cases**
15
+ * - Validating `schemaId`, `credentialId`, or similar parameters in credential
16
+ * and schema factories before creating or resolving documents.
17
+ * - Input validation for APIs that accept URI identifiers (e.g. fetch by ID).
18
+ * - Guarding helpers that resolve or dereference IDs (e.g. document loaders,
19
+ * schema registries) from invalid input.
20
+ *
21
+ * **Examples**
22
+ *
23
+ * Valid — URLs:
24
+ * validateId('schemaId', 'https://example.com/schemas/v1');
25
+ * validateId('id', 'http://example.com:8080/path?q=1');
26
+ *
27
+ * Valid — DIDs (case-insensitive `did:` prefix):
28
+ * validateId('subject', 'did:example:123456789');
29
+ * validateId('subject', 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK');
30
+ *
31
+ * Throws — missing or invalid:
32
+ * validateId('id', ''); // Error: Parameter "id" is required
33
+ * validateId('id', null); // Error: Parameter "id" is required
34
+ * validateId('id', 'not-a-uri'); // Error: Parameter "id" must be a URL, received: "not-a-uri"
35
+ *
36
+ * @param name - Parameter name used in error messages (e.g. `"schemaId"`, `"credentialId"`).
37
+ * @param value - The value to validate (`string`, `null`, or `undefined`).
38
+ * @throws {Error} When `value` is falsy, or when it is not a URL and does not start with `did:`.
39
+ */
40
+ const validateId = (name, value) => {
41
+ if (!value) {
42
+ throw new Error(`Parameter "${name}" is required`);
43
+ }
44
+ const isURI = value.toLowerCase().startsWith('did:') || (0, validator_1.isURL)(value);
45
+ if (isURI) {
46
+ return;
47
+ }
48
+ throw new Error(`Parameter "${name}" must be a URL, received: "${value}"`);
49
+ };
50
+ exports.default = validateId;
51
+ //# sourceMappingURL=validateId.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateId.js","sourceRoot":"","sources":["../../src/helpers/validateId.ts"],"names":[],"mappings":";;AAAA,yCAAkC;AAElC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,KAAgC,EAAE,EAAE;IACpE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,eAAe,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,IAAA,iBAAK,EAAC,KAAK,CAAC,CAAC;IAErE,IAAI,KAAK,EAAE,CAAC;QACV,OAAO;IACT,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,+BAA+B,KAAK,GAAG,CAAC,CAAC;AAC7E,CAAC,CAAC;AAEF,kBAAe,UAAU,CAAC"}
@@ -0,0 +1,7 @@
1
+ import Schema from './Schema';
2
+ import Validator from './Validator';
3
+ import documentLoader from './ld/documentLoader';
4
+ import ValidationError from './ValidationError';
5
+ import CredentialFactory from './CredentialFactory';
6
+ export { Schema, Validator, documentLoader, ValidationError, CredentialFactory };
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,UAAU,CAAC;AAC9B,OAAO,SAAS,MAAM,aAAa,CAAC;AACpC,OAAO,cAAc,MAAM,qBAAqB,CAAC;AACjD,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAChD,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EACL,MAAM,EACN,SAAS,EACT,cAAc,EACd,eAAe,EACf,iBAAiB,EAClB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CredentialFactory = exports.ValidationError = exports.documentLoader = exports.Validator = exports.Schema = void 0;
7
+ const Schema_1 = __importDefault(require("./Schema"));
8
+ exports.Schema = Schema_1.default;
9
+ const Validator_1 = __importDefault(require("./Validator"));
10
+ exports.Validator = Validator_1.default;
11
+ const documentLoader_1 = __importDefault(require("./ld/documentLoader"));
12
+ exports.documentLoader = documentLoader_1.default;
13
+ const ValidationError_1 = __importDefault(require("./ValidationError"));
14
+ exports.ValidationError = ValidationError_1.default;
15
+ const CredentialFactory_1 = __importDefault(require("./CredentialFactory"));
16
+ exports.CredentialFactory = CredentialFactory_1.default;
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,sDAA8B;AAO5B,iBAPK,gBAAM,CAOL;AANR,4DAAoC;AAOlC,oBAPK,mBAAS,CAOL;AANX,yEAAiD;AAO/C,yBAPK,wBAAc,CAOL;AANhB,wEAAgD;AAO9C,0BAPK,yBAAe,CAOL;AANjB,4EAAoD;AAOlD,4BAPK,2BAAiB,CAOL"}
@@ -0,0 +1,8 @@
1
+ /** Returns document from the context via url */
2
+ declare const documentLoader: (documentUrl: string) => {
3
+ document: Record<string, unknown>;
4
+ contextUrl: null;
5
+ documentUrl: string;
6
+ };
7
+ export default documentLoader;
8
+ //# sourceMappingURL=documentLoader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documentLoader.d.ts","sourceRoot":"","sources":["../../src/ld/documentLoader.ts"],"names":[],"mappings":"AAQA,gDAAgD;AAChD,QAAA,MAAM,cAAc,GAAI,aAAa,MAAM;;;;CAgB1C,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const security_context_1 = require("security-context");
4
+ const credentials_context_1 = require("credentials-context");
5
+ const CONTEXTS = new Map([
6
+ ...security_context_1.contexts,
7
+ ...credentials_context_1.contexts
8
+ ]);
9
+ /** Returns document from the context via url */
10
+ const documentLoader = (documentUrl) => {
11
+ const contextUrl = null;
12
+ const [url] = documentUrl.split('#');
13
+ const document = CONTEXTS.get(url);
14
+ if (!document) {
15
+ throw new Error(`Custom context "${documentUrl}" is not supported`);
16
+ }
17
+ return {
18
+ document,
19
+ contextUrl,
20
+ documentUrl
21
+ };
22
+ };
23
+ exports.default = documentLoader;
24
+ //# sourceMappingURL=documentLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documentLoader.js","sourceRoot":"","sources":["../../src/ld/documentLoader.ts"],"names":[],"mappings":";;AAAA,uDAAmE;AACnE,6DAAyE;AAEzE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC;IACvB,GAAG,2BAAmB;IACtB,GAAG,8BAAsB;CAC1B,CAAC,CAAC;AAEH,gDAAgD;AAChD,MAAM,cAAc,GAAG,CAAC,WAAmB,EAAE,EAAE;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC;IAExB,MAAM,CAAE,GAAG,CAAE,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEvC,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAEnC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,mBAAmB,WAAW,oBAAoB,CAAC,CAAC;IACtE,CAAC;IAED,OAAO;QACL,QAAQ;QACR,UAAU;QACV,WAAW;KACZ,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,cAAc,CAAC"}
@@ -0,0 +1,10 @@
1
+ export type PropertySchema = {
2
+ '@type'?: string;
3
+ $ref?: string;
4
+ type?: string;
5
+ format?: string;
6
+ };
7
+ /** Returns linked data attribute type for a property schema, unless @type is defined */
8
+ declare const getLinkedDataAttributeType: (propertySchema: PropertySchema) => string | undefined;
9
+ export default getLinkedDataAttributeType;
10
+ //# sourceMappingURL=getLinkedDataAttributeType.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getLinkedDataAttributeType.d.ts","sourceRoot":"","sources":["../../src/ld/getLinkedDataAttributeType.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,wFAAwF;AACxF,QAAA,MAAM,0BAA0B,GAAI,gBAAgB,cAAc,KAAG,MAAM,GAAG,SAiC7E,CAAC;AAEF,eAAe,0BAA0B,CAAC"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const lodash_1 = require("lodash");
4
+ /** Returns linked data attribute type for a property schema, unless @type is defined */
5
+ const getLinkedDataAttributeType = (propertySchema) => {
6
+ const isOverriden = !!(0, lodash_1.get)(propertySchema, '@type');
7
+ if (isOverriden) {
8
+ return (0, lodash_1.get)(propertySchema, '@type');
9
+ }
10
+ // TODO: Add support for all types and formats, extend schema library with
11
+ // support for additional formats, e.g. URL, Duration etc.
12
+ const { type, format } = propertySchema;
13
+ const isDate = format === 'date';
14
+ const isNumber = type === 'number';
15
+ const isInteger = type === 'integer';
16
+ const isDateTime = format === 'date-time';
17
+ if (isInteger) {
18
+ return 'schema:Integer';
19
+ }
20
+ if (isNumber) {
21
+ return 'schema:Number';
22
+ }
23
+ if (isDate) {
24
+ return 'schema:Date';
25
+ }
26
+ if (isDateTime) {
27
+ return 'schema:DateTime';
28
+ }
29
+ return;
30
+ };
31
+ exports.default = getLinkedDataAttributeType;
32
+ //# sourceMappingURL=getLinkedDataAttributeType.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getLinkedDataAttributeType.js","sourceRoot":"","sources":["../../src/ld/getLinkedDataAttributeType.ts"],"names":[],"mappings":";;AAAA,mCAA6B;AAS7B,wFAAwF;AACxF,MAAM,0BAA0B,GAAG,CAAC,cAA8B,EAAsB,EAAE;IACxF,MAAM,WAAW,GAAG,CAAC,CAAC,IAAA,YAAG,EAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IAEnD,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,IAAA,YAAG,EAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,0EAA0E;IAC1E,gEAAgE;IAChE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC;IAExC,MAAM,MAAM,GAAG,MAAM,KAAK,MAAM,CAAC;IACjC,MAAM,QAAQ,GAAG,IAAI,KAAK,QAAQ,CAAC;IACnC,MAAM,SAAS,GAAG,IAAI,KAAK,SAAS,CAAC;IACrC,MAAM,UAAU,GAAG,MAAM,KAAK,WAAW,CAAC;IAE1C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED,OAAO;AACT,CAAC,CAAC;AAEF,kBAAe,0BAA0B,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { type PropertySchema } from './getLinkedDataAttributeType';
2
+ export type { PropertySchema };
3
+ type ContextProperty = {
4
+ '@id': string;
5
+ '@type'?: string;
6
+ };
7
+ type ContextHeader = {
8
+ '@vocab': string;
9
+ '@version': number;
10
+ '@protected': boolean;
11
+ schema?: string;
12
+ };
13
+ export type LinkedDataContext = ContextHeader & {
14
+ [key: string]: ContextProperty | string | number | boolean | undefined;
15
+ };
16
+ /** Returns linked data context for a properties object */
17
+ declare const getLinkedDataContext: (properties: Record<string, PropertySchema>, vocabUri: string) => LinkedDataContext;
18
+ export default getLinkedDataContext;
19
+ //# sourceMappingURL=getLinkedDataContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getLinkedDataContext.d.ts","sourceRoot":"","sources":["../../src/ld/getLinkedDataContext.ts"],"names":[],"mappings":"AAAA,OAAmC,EAAE,KAAK,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE/F,YAAY,EAAE,cAAc,EAAE,CAAC;AAU/B,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG;IAC9C,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;CACxE,CAAC;AAEF,0DAA0D;AAC1D,QAAA,MAAM,oBAAoB,GAAI,YAAY,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,UAAU,MAAM,KAAG,iBAgD5F,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const getLinkedDataAttributeType_1 = __importDefault(require("./getLinkedDataAttributeType"));
7
+ const SCHEMA_ORG_URI = 'https://schema.org/';
8
+ const PROTECTED_PROPERTIES = [
9
+ 'id',
10
+ 'type',
11
+ 'schema'
12
+ ];
13
+ /** Returns linked data context for a properties object */
14
+ const getLinkedDataContext = (properties, vocabUri) => {
15
+ const context = {};
16
+ // TODO: Add support for embedded object, array and enum.
17
+ for (const key in properties) {
18
+ const propertySchema = properties[key];
19
+ const isProtected = PROTECTED_PROPERTIES.includes(key) ||
20
+ key.startsWith('@');
21
+ if (isProtected) {
22
+ continue;
23
+ }
24
+ context[key] = { '@id': key };
25
+ const { $ref } = propertySchema;
26
+ if ($ref) {
27
+ continue;
28
+ }
29
+ const linkedDataType = (0, getLinkedDataAttributeType_1.default)(propertySchema);
30
+ if (linkedDataType) {
31
+ context[key]['@type'] = linkedDataType;
32
+ }
33
+ }
34
+ const vocab = vocabUri.endsWith('/') || vocabUri.endsWith('#') ? vocabUri : `${vocabUri}#`;
35
+ const contextHeader = {
36
+ '@vocab': vocab,
37
+ '@version': 1.1,
38
+ '@protected': true
39
+ };
40
+ const isSchemaOrgDomain = vocab === SCHEMA_ORG_URI;
41
+ if (!isSchemaOrgDomain) {
42
+ contextHeader.schema = SCHEMA_ORG_URI;
43
+ }
44
+ return {
45
+ ...contextHeader,
46
+ ...context
47
+ };
48
+ };
49
+ exports.default = getLinkedDataContext;
50
+ //# sourceMappingURL=getLinkedDataContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getLinkedDataContext.js","sourceRoot":"","sources":["../../src/ld/getLinkedDataContext.ts"],"names":[],"mappings":";;;;;AAAA,8FAA+F;AAI/F,MAAM,cAAc,GAAG,qBAAqB,CAAC;AAE7C,MAAM,oBAAoB,GAAG;IAC3B,IAAI;IACJ,MAAM;IACN,QAAQ;CACT,CAAC;AAkBF,0DAA0D;AAC1D,MAAM,oBAAoB,GAAG,CAAC,UAA0C,EAAE,QAAgB,EAAqB,EAAE;IAC/G,MAAM,OAAO,GAAG,EAAqC,CAAC;IAEtD,yDAAyD;IACzD,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,cAAc,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAEvC,MAAM,WAAW,GACf,oBAAoB,CAAC,QAAQ,CAAC,GAAG,CAAC;YAClC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAEtB,IAAI,WAAW,EAAE,CAAC;YAChB,SAAS;QACX,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QAE9B,MAAM,EAAE,IAAI,EAAE,GAAG,cAAc,CAAC;QAEhC,IAAI,IAAI,EAAE,CAAC;YACT,SAAS;QACX,CAAC;QAED,MAAM,cAAc,GAAG,IAAA,oCAA0B,EAAC,cAAc,CAAC,CAAC;QAElE,IAAI,cAAc,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,cAAc,CAAC;QACzC,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,CAAC;IAE3F,MAAM,aAAa,GAAG;QACpB,QAAQ,EAAE,KAAK;QACf,UAAU,EAAE,GAAG;QACf,YAAY,EAAE,IAAI;KACF,CAAC;IAEnB,MAAM,iBAAiB,GAAG,KAAK,KAAK,cAAc,CAAC;IAEnD,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,aAAa,CAAC,MAAM,GAAG,cAAc,CAAC;IACxC,CAAC;IAED,OAAO;QACL,GAAG,aAAa;QAChB,GAAG,OAAO;KACX,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,oBAAoB,CAAC"}
package/eslint.config.mjs CHANGED
@@ -1,55 +1,35 @@
1
- import globals from "globals";
2
- import path from "node:path";
3
- import { fileURLToPath } from "node:url";
4
- import js from "@eslint/js";
5
- import { FlatCompat } from "@eslint/eslintrc";
6
-
7
- const __filename = fileURLToPath(import.meta.url);
8
- const __dirname = path.dirname(__filename);
9
- const compat = new FlatCompat({
10
- baseDirectory: __dirname,
11
- recommendedConfig: js.configs.recommended,
12
- allConfig: js.configs.all
13
- });
14
-
15
- export default [...compat.extends("eslint:recommended"), {
1
+ import jsdoc from 'eslint-plugin-jsdoc';
2
+ import eslint from '@eslint/js';
3
+ import globals from 'globals';
4
+ import tseslint from 'typescript-eslint';
5
+ import { globalIgnores } from 'eslint/config';
6
+
7
+ export default tseslint.config(
8
+ globalIgnores([ '**/dist/', '**/coverage/' ]),
9
+ {
16
10
  languageOptions: {
17
- globals: {
18
- ...globals.node,
19
- ...globals.mocha,
20
- },
21
-
22
- ecmaVersion: 2018,
23
- sourceType: "commonjs",
11
+ globals: {
12
+ ...globals.node,
13
+ },
24
14
  },
25
-
26
- rules: {
27
- "comma-style": "error",
28
- "consistent-this": ["error", "_this"],
29
-
30
- indent: ["error", 2, {
31
- SwitchCase: 1,
32
- VariableDeclarator: 2,
33
- }],
34
-
35
- "keyword-spacing": "error",
36
- "no-multi-spaces": "off",
37
- "no-spaced-func": "error",
38
- "no-trailing-spaces": "error",
39
- quotes: ["error", "single"],
40
- semi: ["error", "never"],
41
- curly: ["error"],
42
- "prefer-arrow-callback": "error",
43
- "space-before-blocks": "error",
44
-
45
- "space-before-function-paren": [1, {
46
- anonymous: "always",
47
- named: "never",
48
- }],
49
-
50
- "space-infix-ops": "error",
51
- "space-unary-ops": "error",
52
- "no-return-await": "error",
53
- eqeqeq: "error",
15
+ plugins: {
16
+ jsdoc,
54
17
  },
55
- }];
18
+ rules: {
19
+ semi: ['error', 'always'],
20
+ quotes: ['error', 'single'],
21
+ 'jsdoc/require-jsdoc': ['error', {
22
+ require: {
23
+ ArrowFunctionExpression: true,
24
+ ClassDeclaration: true,
25
+ ClassExpression: true,
26
+ FunctionDeclaration: true,
27
+ FunctionExpression: true,
28
+ MethodDefinition: true,
29
+ },
30
+ }],
31
+ }
32
+ },
33
+ eslint.configs.recommended,
34
+ tseslint.configs.recommended
35
+ );
@@ -0,0 +1,27 @@
1
+ import { Schema, CredentialFactory } from '../../src';
2
+
3
+ const accountSchema = new Schema({
4
+ id: {},
5
+ username: { required: true },
6
+ createdAt: { format: 'date-time', required: true },
7
+ dateOfBirth: { format: 'date' }
8
+ }, 'Account');
9
+
10
+ const factory = new CredentialFactory('https://example.com/schema/AccountV1', [ accountSchema ]);
11
+
12
+ /** Creates account credetial for username */
13
+ const createAccountCredential = (holder: string, username: string) => {
14
+ const id = `https://example.com/account/${username}`;
15
+
16
+ const createdAt = new Date().toISOString();
17
+
18
+ const subject = {
19
+ id: holder,
20
+ username,
21
+ createdAt
22
+ };
23
+
24
+ return factory.createCredential(id, holder, subject);
25
+ };
26
+
27
+ export default createAccountCredential;
@@ -0,0 +1,115 @@
1
+ import { Schema, CredentialFactory } from '../../src';
2
+
3
+ const GAME_NAME = 'MineSweeper';
4
+ const GAME_VERSION = '1.0';
5
+
6
+ const SCHEMA_ORG_URI = 'https://schema.org/';
7
+
8
+ const playerSchema = new Schema({
9
+ id: {},
10
+ hasVideoGameScore: {
11
+ $ref: 'VideoGameScore',
12
+ required: true
13
+ }
14
+ }, 'Player');
15
+
16
+ const videoGameSchema = new Schema({
17
+ id: {},
18
+ name: {
19
+ type: 'string',
20
+ required: true
21
+ },
22
+ version: {
23
+ type: 'string',
24
+ required: true
25
+ }
26
+ }, 'VideoGame', SCHEMA_ORG_URI);
27
+
28
+ const videoGameScoreSchema = new Schema({
29
+ game: {
30
+ $ref: 'VideoGame',
31
+ required: true
32
+ },
33
+ wins: {
34
+ type: 'integer',
35
+ required: true
36
+ },
37
+ losses: {
38
+ type: 'integer',
39
+ required: true
40
+ },
41
+ winRate: {
42
+ type: 'number',
43
+ required: true
44
+ },
45
+ bestScore: {
46
+ type: 'integer',
47
+ required: true
48
+ },
49
+ // TODO: Add duration as format:
50
+ endurance: {
51
+ type: 'string',
52
+ '@type': 'schema:Duration',
53
+ required: true,
54
+ },
55
+ dateCreated: {
56
+ type: 'string',
57
+ 'format': 'date-time',
58
+ required: true
59
+ },
60
+ bestRoundTime: {
61
+ type: 'integer',
62
+ required: true
63
+ }
64
+ // difficultyLevel:
65
+ // enum:
66
+ // - EASY
67
+ // - MEDIUM
68
+ // - HARD
69
+ // required: true
70
+ }, 'VideoGameScore');
71
+
72
+ const CREDENTIAL_URI = `https://example.com/schema/${GAME_NAME}ScoreV1`;
73
+
74
+ const SCHEMAS = [
75
+ playerSchema,
76
+ videoGameSchema,
77
+ videoGameScoreSchema
78
+ ];
79
+
80
+ const factory = new CredentialFactory(CREDENTIAL_URI, SCHEMAS);
81
+
82
+ /** Creates score credential for MineSweeper game */
83
+ const createMineSweeperScoreCredential = (
84
+ gameId: string,
85
+ playerId: string,
86
+ playerScore: {
87
+ wins: number;
88
+ losses: number;
89
+ winRate: number;
90
+ bestScore: number;
91
+ endurance: string;
92
+ dateCreated: string;
93
+ bestRoundTime: number;
94
+ }
95
+ ) => {
96
+ const credentialId = 'https://example.com/credentials/CREDENTIAL_ID';
97
+
98
+ const game = {
99
+ id: gameId,
100
+ name: GAME_NAME,
101
+ version: GAME_VERSION
102
+ };
103
+
104
+ const player = {
105
+ id: playerId,
106
+ hasVideoGameScore: {
107
+ ...playerScore,
108
+ game
109
+ }
110
+ };
111
+
112
+ return factory.createCredential(credentialId, playerId, player);
113
+ };
114
+
115
+ export default createMineSweeperScoreCredential;
@@ -0,0 +1,7 @@
1
+ import createAccountCredential from './credentials/createAccountCredential';
2
+ import createMineSweeperScoreCredential from './credentials/createMineSweeperScoreCredential';
3
+
4
+ export {
5
+ createAccountCredential,
6
+ createMineSweeperScoreCredential
7
+ };
@@ -0,0 +1,27 @@
1
+ import { Schema } from '../../src';
2
+
3
+ const FavoriteItemSchema = new Schema({
4
+ id: {
5
+ required: true,
6
+ },
7
+ name: {
8
+ required: true,
9
+ },
10
+ description: {},
11
+ status: {
12
+ $ref: 'Status',
13
+ default: 'Pending',
14
+ },
15
+ categories: {
16
+ items: {
17
+ enum: [
18
+ 'Education',
19
+ 'Work',
20
+ 'Lifestyle',
21
+ 'Games'
22
+ ]
23
+ }
24
+ }
25
+ }, 'FavoriteItemSchema');
26
+
27
+ export default FavoriteItemSchema;
@@ -1,5 +1,7 @@
1
1
  age:
2
2
  type: number
3
+ minimum: 0
4
+ maximum: 199
3
5
 
4
6
  height:
5
7
  type: number
@@ -0,0 +1,29 @@
1
+ import { Schema } from '../../src';
2
+
3
+ const PreferencesSchema = new Schema({
4
+ age:{
5
+ type: 'number',
6
+ minimum: 0,
7
+ maximum: 199,
8
+ },
9
+ height: {
10
+ type: 'number'
11
+ },
12
+ isNotificationEnabled: {
13
+ type: 'boolean'
14
+ },
15
+ shouldSendEmails: {
16
+ type: 'boolean'
17
+ },
18
+ shouldSendSMS: {
19
+ type: 'boolean'
20
+ },
21
+ hasPaymentMethod: {
22
+ type: 'boolean'
23
+ },
24
+ hasPositiveBalance: {
25
+ type: 'boolean'
26
+ }
27
+ }, 'PreferencesSchema');
28
+
29
+ export default PreferencesSchema;
@@ -0,0 +1,91 @@
1
+ import { Schema } from '../../src';
2
+
3
+ const ProfileSchema = new Schema({
4
+ name: {
5
+ required: true,
6
+ minLength: 3,
7
+ maxLength: 128,
8
+ },
9
+ // NOTE: Referenced enum:
10
+ status: {
11
+ $ref: 'Status',
12
+ default: 'Pending',
13
+ },
14
+ // NOTE: Nested enum:
15
+ gender: {
16
+ enum: [ 'Male', 'Female', 'Other' ],
17
+ default: 'Other'
18
+ },
19
+ // NOTE: Nested object:
20
+ contactDetails: {
21
+ required: true,
22
+ properties: {
23
+ email: {
24
+ type: 'string',
25
+ format: 'email',
26
+ required: true,
27
+ },
28
+ secondaryEmail: {
29
+ type: 'string',
30
+ format: 'email',
31
+ },
32
+ mobileNumber: {
33
+ type: 'string',
34
+ pattern: '^[0-9]{1,20}$',
35
+ default: '380504112171',
36
+ }
37
+ }
38
+ },
39
+ // NOTE: Array of nested objects:
40
+ locations: {
41
+ items: {
42
+ properties: {
43
+ name: {
44
+ required: true,
45
+ },
46
+ address: {
47
+ properties: {
48
+ country: {
49
+ required: true,
50
+ default: 'Ukraine',
51
+ },
52
+ city: {
53
+ required: true,
54
+ },
55
+ addressLine1: {
56
+ required: true,
57
+ },
58
+ addressLine2: {},
59
+ zip: {
60
+ required: true,
61
+ },
62
+ type: {
63
+ enum: [ 'Primary', 'Secondary' ],
64
+ default: 'Secondary'
65
+ }
66
+ },
67
+ }
68
+ }
69
+ }
70
+ },
71
+ // NOTE: Array of strings:
72
+ tags: {
73
+ type: 'array',
74
+ },
75
+ // NOTE: Array of referenced objects:
76
+ favoriteItems: {
77
+ items: {
78
+ $ref: 'FavoriteItem',
79
+ }
80
+ },
81
+ // NOTE: Referenced object:
82
+ preferences: {
83
+ $ref: 'Preferences',
84
+ },
85
+ // NOTE: Nested object without properties:
86
+ hash: {
87
+ type: 'object',
88
+ }
89
+ }, 'ProfileSchema');
90
+
91
+ export default ProfileSchema;
@@ -0,0 +1,3 @@
1
+ enum:
2
+ - PENDING
3
+ - ACTIVE