@fedify/vocab-tools 2.1.0-dev.565 → 2.1.0-dev.599

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/deno.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/vocab-tools",
3
- "version": "2.1.0-dev.565+b4d238a9",
3
+ "version": "2.1.0-dev.599+1ff26884",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": "./src/mod.ts"
package/dist/mod.cjs CHANGED
@@ -31,7 +31,7 @@ const es_toolkit = __toESM(require("es-toolkit"));
31
31
 
32
32
  //#region deno.json
33
33
  var name = "@fedify/vocab-tools";
34
- var version = "2.1.0-dev.565+b4d238a9";
34
+ var version = "2.1.0-dev.599+1ff26884";
35
35
  var license = "MIT";
36
36
  var exports$1 = { ".": "./src/mod.ts" };
37
37
  var author = {
@@ -163,6 +163,30 @@ const scalarTypes = {
163
163
  return `${v}["@value"]`;
164
164
  }
165
165
  },
166
+ "http://www.w3.org/2001/XMLSchema#decimal": {
167
+ name: "Decimal",
168
+ typeGuard(v) {
169
+ return `typeof ${v} === "string" && isDecimal(${v})`;
170
+ },
171
+ encoder(v) {
172
+ return `{
173
+ "@type": "http://www.w3.org/2001/XMLSchema#decimal",
174
+ "@value": ${v},
175
+ }`;
176
+ },
177
+ compactEncoder(v) {
178
+ return v;
179
+ },
180
+ dataCheck(v) {
181
+ return `typeof ${v} === "object" && "@type" in ${v}
182
+ && ${v}["@type"] === "http://www.w3.org/2001/XMLSchema#decimal"
183
+ && "@value" in ${v} && typeof ${v}["@value"] === "string"
184
+ && canParseDecimal(${v}["@value"])`;
185
+ },
186
+ decoder(v) {
187
+ return `parseDecimal(${v}["@value"])`;
188
+ }
189
+ },
166
190
  "http://www.w3.org/2001/XMLSchema#string": {
167
191
  name: "string",
168
192
  typeGuard(v) {
@@ -632,6 +656,26 @@ function hasSingularAccessor(property) {
632
656
  if (property.functional === true) return true;
633
657
  return isNonFunctionalProperty(property) && property.singularAccessor === true;
634
658
  }
659
+ const XSD_STRING_URI = "http://www.w3.org/2001/XMLSchema#string";
660
+ const XSD_DECIMAL_URI = "http://www.w3.org/2001/XMLSchema#decimal";
661
+ /**
662
+ * Validates schema combinations that cannot be represented safely by the
663
+ * generated code.
664
+ *
665
+ * In particular, `xsd:string` and `xsd:decimal` cannot coexist in the same
666
+ * property range because both are represented as runtime strings, which makes
667
+ * JSON-LD serialization ambiguous and order-dependent.
668
+ *
669
+ * @param types The loaded type schemas to validate.
670
+ * @throws {TypeError} Thrown when an unsupported range combination is found.
671
+ */
672
+ function validateTypeSchemas(types) {
673
+ for (const type of Object.values(types)) for (const property of type.properties) {
674
+ const hasString = property.range.includes(XSD_STRING_URI);
675
+ const hasDecimal = property.range.includes(XSD_DECIMAL_URI);
676
+ if (hasString && hasDecimal) throw new TypeError(`The property ${type.name}.${property.singularName} cannot have both xsd:string and xsd:decimal in its range because the generated encoder cannot disambiguate them at runtime.`);
677
+ }
678
+ }
635
679
  /**
636
680
  * An error that occurred while loading a schema file.
637
681
  */
@@ -1914,24 +1958,29 @@ async function* generateClass(typeUri, types) {
1914
1958
  * @returns The source code of the generated classes.
1915
1959
  */
1916
1960
  async function* generateClasses(types) {
1917
- yield "// deno-lint-ignore-file ban-unused-ignore prefer-const\n";
1918
- yield "// @ts-ignore TS7016\n";
1919
- yield "import jsonld from \"jsonld\";\n";
1961
+ validateTypeSchemas(types);
1962
+ const runtimeImports = [
1963
+ "canParseDecimal",
1964
+ "decodeMultibase",
1965
+ "type Decimal",
1966
+ "type DocumentLoader",
1967
+ "encodeMultibase",
1968
+ "exportMultibaseKey",
1969
+ "exportSpki",
1970
+ "getDocumentLoader",
1971
+ "importMultibaseKey",
1972
+ "importPem",
1973
+ "isDecimal",
1974
+ "LanguageString",
1975
+ "parseDecimal",
1976
+ "type RemoteDocument"
1977
+ ];
1978
+ yield "// deno-lint-ignore-file ban-unused-ignore no-unused-vars prefer-const verbatim-module-syntax\n";
1979
+ yield "import jsonld from \"@fedify/vocab-runtime/jsonld\";\n";
1920
1980
  yield "import { getLogger } from \"@logtape/logtape\";\n";
1921
1981
  yield `import { type Span, SpanStatusCode, type TracerProvider, trace }
1922
1982
  from "@opentelemetry/api";\n`;
1923
- yield `import {
1924
- decodeMultibase,
1925
- type DocumentLoader,
1926
- encodeMultibase,
1927
- exportMultibaseKey,
1928
- exportSpki,
1929
- getDocumentLoader,
1930
- importMultibaseKey,
1931
- importPem,
1932
- LanguageString,
1933
- type RemoteDocument,
1934
- } from "@fedify/vocab-runtime";\n`;
1983
+ yield `import {\n ${runtimeImports.join(",\n ")}\n} from "@fedify/vocab-runtime";\n`;
1935
1984
  yield "\n\n";
1936
1985
  const sorted = sortTopologically(types);
1937
1986
  for (const typeUri of sorted) for await (const code of generateClass(typeUri, types)) yield code;
package/dist/mod.js CHANGED
@@ -8,7 +8,7 @@ import { pascalCase } from "es-toolkit";
8
8
 
9
9
  //#region deno.json
10
10
  var name = "@fedify/vocab-tools";
11
- var version = "2.1.0-dev.565+b4d238a9";
11
+ var version = "2.1.0-dev.599+1ff26884";
12
12
  var license = "MIT";
13
13
  var exports = { ".": "./src/mod.ts" };
14
14
  var author = {
@@ -140,6 +140,30 @@ const scalarTypes = {
140
140
  return `${v}["@value"]`;
141
141
  }
142
142
  },
143
+ "http://www.w3.org/2001/XMLSchema#decimal": {
144
+ name: "Decimal",
145
+ typeGuard(v) {
146
+ return `typeof ${v} === "string" && isDecimal(${v})`;
147
+ },
148
+ encoder(v) {
149
+ return `{
150
+ "@type": "http://www.w3.org/2001/XMLSchema#decimal",
151
+ "@value": ${v},
152
+ }`;
153
+ },
154
+ compactEncoder(v) {
155
+ return v;
156
+ },
157
+ dataCheck(v) {
158
+ return `typeof ${v} === "object" && "@type" in ${v}
159
+ && ${v}["@type"] === "http://www.w3.org/2001/XMLSchema#decimal"
160
+ && "@value" in ${v} && typeof ${v}["@value"] === "string"
161
+ && canParseDecimal(${v}["@value"])`;
162
+ },
163
+ decoder(v) {
164
+ return `parseDecimal(${v}["@value"])`;
165
+ }
166
+ },
143
167
  "http://www.w3.org/2001/XMLSchema#string": {
144
168
  name: "string",
145
169
  typeGuard(v) {
@@ -609,6 +633,26 @@ function hasSingularAccessor(property) {
609
633
  if (property.functional === true) return true;
610
634
  return isNonFunctionalProperty(property) && property.singularAccessor === true;
611
635
  }
636
+ const XSD_STRING_URI = "http://www.w3.org/2001/XMLSchema#string";
637
+ const XSD_DECIMAL_URI = "http://www.w3.org/2001/XMLSchema#decimal";
638
+ /**
639
+ * Validates schema combinations that cannot be represented safely by the
640
+ * generated code.
641
+ *
642
+ * In particular, `xsd:string` and `xsd:decimal` cannot coexist in the same
643
+ * property range because both are represented as runtime strings, which makes
644
+ * JSON-LD serialization ambiguous and order-dependent.
645
+ *
646
+ * @param types The loaded type schemas to validate.
647
+ * @throws {TypeError} Thrown when an unsupported range combination is found.
648
+ */
649
+ function validateTypeSchemas(types) {
650
+ for (const type of Object.values(types)) for (const property of type.properties) {
651
+ const hasString = property.range.includes(XSD_STRING_URI);
652
+ const hasDecimal = property.range.includes(XSD_DECIMAL_URI);
653
+ if (hasString && hasDecimal) throw new TypeError(`The property ${type.name}.${property.singularName} cannot have both xsd:string and xsd:decimal in its range because the generated encoder cannot disambiguate them at runtime.`);
654
+ }
655
+ }
612
656
  /**
613
657
  * An error that occurred while loading a schema file.
614
658
  */
@@ -1891,24 +1935,29 @@ async function* generateClass(typeUri, types) {
1891
1935
  * @returns The source code of the generated classes.
1892
1936
  */
1893
1937
  async function* generateClasses(types) {
1894
- yield "// deno-lint-ignore-file ban-unused-ignore prefer-const\n";
1895
- yield "// @ts-ignore TS7016\n";
1896
- yield "import jsonld from \"jsonld\";\n";
1938
+ validateTypeSchemas(types);
1939
+ const runtimeImports = [
1940
+ "canParseDecimal",
1941
+ "decodeMultibase",
1942
+ "type Decimal",
1943
+ "type DocumentLoader",
1944
+ "encodeMultibase",
1945
+ "exportMultibaseKey",
1946
+ "exportSpki",
1947
+ "getDocumentLoader",
1948
+ "importMultibaseKey",
1949
+ "importPem",
1950
+ "isDecimal",
1951
+ "LanguageString",
1952
+ "parseDecimal",
1953
+ "type RemoteDocument"
1954
+ ];
1955
+ yield "// deno-lint-ignore-file ban-unused-ignore no-unused-vars prefer-const verbatim-module-syntax\n";
1956
+ yield "import jsonld from \"@fedify/vocab-runtime/jsonld\";\n";
1897
1957
  yield "import { getLogger } from \"@logtape/logtape\";\n";
1898
1958
  yield `import { type Span, SpanStatusCode, type TracerProvider, trace }
1899
1959
  from "@opentelemetry/api";\n`;
1900
- yield `import {
1901
- decodeMultibase,
1902
- type DocumentLoader,
1903
- encodeMultibase,
1904
- exportMultibaseKey,
1905
- exportSpki,
1906
- getDocumentLoader,
1907
- importMultibaseKey,
1908
- importPem,
1909
- LanguageString,
1910
- type RemoteDocument,
1911
- } from "@fedify/vocab-runtime";\n`;
1960
+ yield `import {\n ${runtimeImports.join(",\n ")}\n} from "@fedify/vocab-runtime";\n`;
1912
1961
  yield "\n\n";
1913
1962
  const sorted = sortTopologically(types);
1914
1963
  for (const typeUri of sorted) for await (const code of generateClass(typeUri, types)) yield code;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/vocab-tools",
3
- "version": "2.1.0-dev.565+b4d238a9",
3
+ "version": "2.1.0-dev.599+1ff26884",
4
4
  "description": "Code generator for Activity Vocabulary APIs",
5
5
  "homepage": "https://fedify.dev/",
6
6
  "repository": {
@@ -1,14 +1,15 @@
1
1
  export const snapshot = {};
2
2
 
3
3
  snapshot[`generateClasses() 1`] = `
4
- "// deno-lint-ignore-file ban-unused-ignore prefer-const
5
- // @ts-ignore TS7016
6
- import jsonld from \\"jsonld\\";
4
+ "// deno-lint-ignore-file ban-unused-ignore no-unused-vars prefer-const verbatim-module-syntax
5
+ import jsonld from \\"@fedify/vocab-runtime/jsonld\\";
7
6
  import { getLogger } from \\"@logtape/logtape\\";
8
7
  import { type Span, SpanStatusCode, type TracerProvider, trace }
9
8
  from \\"@opentelemetry/api\\";
10
9
  import {
10
+ canParseDecimal,
11
11
  decodeMultibase,
12
+ type Decimal,
12
13
  type DocumentLoader,
13
14
  encodeMultibase,
14
15
  exportMultibaseKey,
@@ -16,8 +17,10 @@ import {
16
17
  getDocumentLoader,
17
18
  importMultibaseKey,
18
19
  importPem,
20
+ isDecimal,
19
21
  LanguageString,
20
- type RemoteDocument,
22
+ parseDecimal,
23
+ type RemoteDocument
21
24
  } from \\"@fedify/vocab-runtime\\";
22
25
 
23
26
 
@@ -1,12 +1,13 @@
1
1
  exports[`generateClasses() 1`] = `
2
- "// deno-lint-ignore-file ban-unused-ignore prefer-const
3
- // @ts-ignore TS7016
4
- import jsonld from \\"jsonld\\";
2
+ "// deno-lint-ignore-file ban-unused-ignore no-unused-vars prefer-const verbatim-module-syntax
3
+ import jsonld from \\"@fedify/vocab-runtime/jsonld\\";
5
4
  import { getLogger } from \\"@logtape/logtape\\";
6
5
  import { type Span, SpanStatusCode, type TracerProvider, trace }
7
6
  from \\"@opentelemetry/api\\";
8
7
  import {
8
+ canParseDecimal,
9
9
  decodeMultibase,
10
+ type Decimal,
10
11
  type DocumentLoader,
11
12
  encodeMultibase,
12
13
  exportMultibaseKey,
@@ -14,8 +15,10 @@ import {
14
15
  getDocumentLoader,
15
16
  importMultibaseKey,
16
17
  importPem,
18
+ isDecimal,
17
19
  LanguageString,
18
- type RemoteDocument,
20
+ parseDecimal,
21
+ type RemoteDocument
19
22
  } from \\"@fedify/vocab-runtime\\";
20
23
 
21
24
 
@@ -1,14 +1,15 @@
1
1
  // Bun Snapshot v1, https://bun.sh/docs/test/snapshots
2
2
 
3
3
  exports[`generateClasses() 1`] = `
4
- "// deno-lint-ignore-file ban-unused-ignore prefer-const
5
- // @ts-ignore TS7016
6
- import jsonld from "jsonld";
4
+ "// deno-lint-ignore-file ban-unused-ignore no-unused-vars prefer-const verbatim-module-syntax
5
+ import jsonld from "@fedify/vocab-runtime/jsonld";
7
6
  import { getLogger } from "@logtape/logtape";
8
7
  import { type Span, SpanStatusCode, type TracerProvider, trace }
9
8
  from "@opentelemetry/api";
10
9
  import {
10
+ canParseDecimal,
11
11
  decodeMultibase,
12
+ type Decimal,
12
13
  type DocumentLoader,
13
14
  encodeMultibase,
14
15
  exportMultibaseKey,
@@ -16,8 +17,10 @@ import {
16
17
  getDocumentLoader,
17
18
  importMultibaseKey,
18
19
  importPem,
20
+ isDecimal,
19
21
  LanguageString,
20
- type RemoteDocument,
22
+ parseDecimal,
23
+ type RemoteDocument
21
24
  } from "@fedify/vocab-runtime";
22
25
 
23
26
 
package/src/class.test.ts CHANGED
@@ -1,9 +1,10 @@
1
- import { deepStrictEqual } from "node:assert";
1
+ import { deepStrictEqual, match, rejects } from "node:assert";
2
2
  import { basename, dirname, extname, join } from "node:path";
3
3
  import { test } from "node:test";
4
4
  import metadata from "../deno.json" with { type: "json" };
5
5
  import { generateClasses, sortTopologically } from "./class.ts";
6
- import { loadSchemaFiles } from "./schema.ts";
6
+ import { getDataCheck } from "./type.ts";
7
+ import { loadSchemaFiles, type TypeSchema } from "./schema.ts";
7
8
 
8
9
  test("sortTopologically()", () => {
9
10
  const sorted = sortTopologically({
@@ -64,6 +65,61 @@ test("sortTopologically()", () => {
64
65
  );
65
66
  });
66
67
 
68
+ test("generateClasses() imports the browser-safe jsonld entrypoint", async () => {
69
+ const entireCode = await getEntireCode();
70
+ match(entireCode, /import jsonld from "@fedify\/vocab-runtime\/jsonld";/);
71
+ });
72
+
73
+ test("generateClasses() imports Decimal helpers for xsd:decimal", async () => {
74
+ const entireCode = await getDecimalFixtureCode();
75
+ match(entireCode, /canParseDecimal,/);
76
+ match(entireCode, /isDecimal,/);
77
+ match(entireCode, /type Decimal,/);
78
+ match(entireCode, /parseDecimal/);
79
+ match(entireCode, /amount\?: Decimal \| null;/);
80
+ match(entireCode, /isDecimal\(values\.amount\)/);
81
+ match(entireCode, /parseDecimal\(v\["@value"\]\)/);
82
+ });
83
+
84
+ test("getDataCheck() uses canParseDecimal() for xsd:decimal", () => {
85
+ const check = getDataCheck(
86
+ "http://www.w3.org/2001/XMLSchema#decimal",
87
+ {},
88
+ "v",
89
+ );
90
+ match(check, /canParseDecimal\(v\["@value"\]\)/);
91
+ });
92
+
93
+ test("generateClasses() rejects xsd:string and xsd:decimal unions", async () => {
94
+ await rejects(
95
+ Array.fromAsync(generateClasses({
96
+ "https://example.com/measure": {
97
+ name: "Measure",
98
+ uri: "https://example.com/measure",
99
+ compactName: "Measure",
100
+ entity: false,
101
+ description: "A measure.",
102
+ properties: [
103
+ {
104
+ singularName: "amount",
105
+ functional: true,
106
+ compactName: "amount",
107
+ uri: "https://example.com/amount",
108
+ description: "An exact decimal amount.",
109
+ range: [
110
+ "http://www.w3.org/2001/XMLSchema#decimal",
111
+ "http://www.w3.org/2001/XMLSchema#string",
112
+ ],
113
+ },
114
+ ],
115
+ defaultContext:
116
+ "https://example.com/context" as TypeSchema["defaultContext"],
117
+ },
118
+ })),
119
+ /cannot have both xsd:string and xsd:decimal in its range/,
120
+ );
121
+ });
122
+
67
123
  if ("Deno" in globalThis) {
68
124
  const { assertSnapshot } = await import("@std/testing/snapshot");
69
125
  Deno.test("generateClasses()", async (t) => {
@@ -96,6 +152,31 @@ async function getEntireCode() {
96
152
  return entireCode;
97
153
  }
98
154
 
155
+ async function getDecimalFixtureCode() {
156
+ const types: Record<string, TypeSchema> = {
157
+ "https://example.com/measure": {
158
+ name: "Measure",
159
+ uri: "https://example.com/measure",
160
+ compactName: "Measure",
161
+ entity: false,
162
+ description: "A measure.",
163
+ properties: [
164
+ {
165
+ singularName: "amount",
166
+ functional: true,
167
+ compactName: "amount",
168
+ uri: "https://example.com/amount",
169
+ description: "An exact decimal amount.",
170
+ range: ["http://www.w3.org/2001/XMLSchema#decimal"],
171
+ },
172
+ ],
173
+ defaultContext:
174
+ "https://example.com/context" as TypeSchema["defaultContext"],
175
+ },
176
+ };
177
+ return (await Array.fromAsync(generateClasses(types))).join("");
178
+ }
179
+
99
180
  async function changeNodeSnapshotPath() {
100
181
  const { snapshot } = await import("node:test");
101
182
  snapshot.setResolveSnapshotPath(
package/src/class.ts CHANGED
@@ -3,7 +3,7 @@ import { generateCloner, generateConstructor } from "./constructor.ts";
3
3
  import { generateFields } from "./field.ts";
4
4
  import { generateInspector, generateInspectorPostClass } from "./inspector.ts";
5
5
  import { generateProperties } from "./property.ts";
6
- import type { TypeSchema } from "./schema.ts";
6
+ import { type TypeSchema, validateTypeSchemas } from "./schema.ts";
7
7
  import { emitOverride } from "./type.ts";
8
8
 
9
9
  /**
@@ -117,24 +117,31 @@ async function* generateClass(
117
117
  export async function* generateClasses(
118
118
  types: Record<string, TypeSchema>,
119
119
  ): AsyncIterable<string> {
120
- yield "// deno-lint-ignore-file ban-unused-ignore prefer-const\n";
121
- yield "// @ts-ignore TS7016\n";
122
- yield 'import jsonld from "jsonld";\n';
120
+ validateTypeSchemas(types);
121
+ const runtimeImports = [
122
+ "canParseDecimal",
123
+ "decodeMultibase",
124
+ "type Decimal",
125
+ "type DocumentLoader",
126
+ "encodeMultibase",
127
+ "exportMultibaseKey",
128
+ "exportSpki",
129
+ "getDocumentLoader",
130
+ "importMultibaseKey",
131
+ "importPem",
132
+ "isDecimal",
133
+ "LanguageString",
134
+ "parseDecimal",
135
+ "type RemoteDocument",
136
+ ];
137
+ yield "// deno-lint-ignore-file ban-unused-ignore no-unused-vars prefer-const verbatim-module-syntax\n";
138
+ yield 'import jsonld from "@fedify/vocab-runtime/jsonld";\n';
123
139
  yield 'import { getLogger } from "@logtape/logtape";\n';
124
140
  yield `import { type Span, SpanStatusCode, type TracerProvider, trace }
125
141
  from "@opentelemetry/api";\n`;
126
- yield `import {
127
- decodeMultibase,
128
- type DocumentLoader,
129
- encodeMultibase,
130
- exportMultibaseKey,
131
- exportSpki,
132
- getDocumentLoader,
133
- importMultibaseKey,
134
- importPem,
135
- LanguageString,
136
- type RemoteDocument,
137
- } from "@fedify/vocab-runtime";\n`;
142
+ yield `import {\n ${
143
+ runtimeImports.join(",\n ")
144
+ }\n} from "@fedify/vocab-runtime";\n`;
138
145
  yield "\n\n";
139
146
  const sorted = sortTopologically(types);
140
147
  for (const typeUri of sorted) {
package/src/schema.ts CHANGED
@@ -240,6 +240,38 @@ export function hasSingularAccessor(property: PropertySchema): boolean {
240
240
  property.singularAccessor === true;
241
241
  }
242
242
 
243
+ const XSD_STRING_URI = "http://www.w3.org/2001/XMLSchema#string";
244
+ const XSD_DECIMAL_URI = "http://www.w3.org/2001/XMLSchema#decimal";
245
+
246
+ /**
247
+ * Validates schema combinations that cannot be represented safely by the
248
+ * generated code.
249
+ *
250
+ * In particular, `xsd:string` and `xsd:decimal` cannot coexist in the same
251
+ * property range because both are represented as runtime strings, which makes
252
+ * JSON-LD serialization ambiguous and order-dependent.
253
+ *
254
+ * @param types The loaded type schemas to validate.
255
+ * @throws {TypeError} Thrown when an unsupported range combination is found.
256
+ */
257
+ export function validateTypeSchemas(
258
+ types: Record<string, TypeSchema>,
259
+ ): void {
260
+ for (const type of Object.values(types)) {
261
+ for (const property of type.properties) {
262
+ const hasString = property.range.includes(XSD_STRING_URI);
263
+ const hasDecimal = property.range.includes(XSD_DECIMAL_URI);
264
+ if (hasString && hasDecimal) {
265
+ throw new TypeError(
266
+ `The property ${type.name}.${property.singularName} cannot have ` +
267
+ `both xsd:string and xsd:decimal in its range because the ` +
268
+ `generated encoder cannot disambiguate them at runtime.`,
269
+ );
270
+ }
271
+ }
272
+ }
273
+ }
274
+
243
275
  /**
244
276
  * An error that occurred while loading a schema file.
245
277
  */
package/src/type.ts CHANGED
@@ -108,6 +108,30 @@ const scalarTypes: Record<string, ScalarType> = {
108
108
  return `${v}["@value"]`;
109
109
  },
110
110
  },
111
+ "http://www.w3.org/2001/XMLSchema#decimal": {
112
+ name: "Decimal",
113
+ typeGuard(v) {
114
+ return `typeof ${v} === "string" && isDecimal(${v})`;
115
+ },
116
+ encoder(v) {
117
+ return `{
118
+ "@type": "http://www.w3.org/2001/XMLSchema#decimal",
119
+ "@value": ${v},
120
+ }`;
121
+ },
122
+ compactEncoder(v) {
123
+ return v;
124
+ },
125
+ dataCheck(v) {
126
+ return `typeof ${v} === "object" && "@type" in ${v}
127
+ && ${v}["@type"] === "http://www.w3.org/2001/XMLSchema#decimal"
128
+ && "@value" in ${v} && typeof ${v}["@value"] === "string"
129
+ && canParseDecimal(${v}["@value"])`;
130
+ },
131
+ decoder(v) {
132
+ return `parseDecimal(${v}["@value"])`;
133
+ },
134
+ },
111
135
  "http://www.w3.org/2001/XMLSchema#string": {
112
136
  name: "string",
113
137
  typeGuard(v) {