@globaltypesystem/gts-ts 0.1.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.
- package/.eslintrc.json +16 -0
- package/.github/workflows/ci.yml +198 -0
- package/.gitmodules +3 -0
- package/.prettierrc +7 -0
- package/LICENSE +201 -0
- package/Makefile +64 -0
- package/README.md +298 -0
- package/dist/cast.d.ts +9 -0
- package/dist/cast.d.ts.map +1 -0
- package/dist/cast.js +153 -0
- package/dist/cast.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +318 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/compatibility.d.ts +11 -0
- package/dist/compatibility.d.ts.map +1 -0
- package/dist/compatibility.js +176 -0
- package/dist/compatibility.js.map +1 -0
- package/dist/extract.d.ts +13 -0
- package/dist/extract.d.ts.map +1 -0
- package/dist/extract.js +194 -0
- package/dist/extract.js.map +1 -0
- package/dist/gts.d.ts +18 -0
- package/dist/gts.d.ts.map +1 -0
- package/dist/gts.js +472 -0
- package/dist/gts.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +97 -0
- package/dist/index.js.map +1 -0
- package/dist/query.d.ts +10 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +171 -0
- package/dist/query.js.map +1 -0
- package/dist/relationships.d.ts +7 -0
- package/dist/relationships.d.ts.map +1 -0
- package/dist/relationships.js +80 -0
- package/dist/relationships.js.map +1 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +132 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/server.d.ts +33 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +678 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/types.d.ts +61 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +3 -0
- package/dist/server/types.js.map +1 -0
- package/dist/store.d.ts +39 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +1026 -0
- package/dist/store.js.map +1 -0
- package/dist/types.d.ts +111 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +29 -0
- package/dist/types.js.map +1 -0
- package/dist/x-gts-ref.d.ts +35 -0
- package/dist/x-gts-ref.d.ts.map +1 -0
- package/dist/x-gts-ref.js +304 -0
- package/dist/x-gts-ref.js.map +1 -0
- package/jest.config.js +13 -0
- package/package.json +54 -0
- package/src/cast.ts +179 -0
- package/src/cli/index.ts +315 -0
- package/src/compatibility.ts +201 -0
- package/src/extract.ts +213 -0
- package/src/gts.ts +550 -0
- package/src/index.ts +97 -0
- package/src/query.ts +191 -0
- package/src/relationships.ts +91 -0
- package/src/server/index.ts +112 -0
- package/src/server/server.ts +771 -0
- package/src/server/types.ts +74 -0
- package/src/store.ts +1178 -0
- package/src/types.ts +138 -0
- package/src/x-gts-ref.ts +349 -0
- package/tests/gts.test.ts +525 -0
- package/tsconfig.json +32 -0
package/README.md
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
# GTS TypeScript Implementation
|
|
2
|
+
|
|
3
|
+
A complete TypeScript implementation of the Global Type System (GTS)
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
GTS [Global Type System](https://github.com/globaltypesystem/gts-spec) is a simple, human-readable, globally unique identifier and referencing system for data type definitions (e.g., JSON Schemas) and data instances (e.g., JSON objects). This TypeScript implementation provides type-safe operations for working with GTS identifiers.
|
|
8
|
+
|
|
9
|
+
## Roadmap
|
|
10
|
+
|
|
11
|
+
Featureset:
|
|
12
|
+
|
|
13
|
+
- [x] **OP#1 - ID Validation**: Verify identifier syntax using regex patterns
|
|
14
|
+
- [x] **OP#2 - ID Extraction**: Fetch identifiers from JSON objects or JSON Schema documents
|
|
15
|
+
- [x] **OP#3 - ID Parsing**: Decompose identifiers into constituent parts (vendor, package, namespace, type, version, etc.)
|
|
16
|
+
- [x] **OP#4 - ID Pattern Matching**: Match identifiers against patterns containing wildcards
|
|
17
|
+
- [x] **OP#5 - ID to UUID Mapping**: Generate deterministic UUIDs from GTS identifiers
|
|
18
|
+
- [x] **OP#6 - Schema Validation**: Validate object instances against their corresponding schemas
|
|
19
|
+
- [x] **OP#7 - Relationship Resolution**: Load all schemas and instances, resolve inter-dependencies, and detect broken references
|
|
20
|
+
- [x] **OP#8 - Compatibility Checking**: Verify that schemas with different MINOR versions are compatible
|
|
21
|
+
- [x] **OP#8.1 - Backward compatibility checking**
|
|
22
|
+
- [x] **OP#8.2 - Forward compatibility checking**
|
|
23
|
+
- [x] **OP#8.3 - Full compatibility checking**
|
|
24
|
+
- [x] **OP#9 - Version Casting**: Transform instances between compatible MINOR versions
|
|
25
|
+
- [x] **OP#10 - Query Execution**: Filter identifier collections using the GTS query language
|
|
26
|
+
- [x] **OP#11 - Attribute Access**: Retrieve property values and metadata using the attribute selector (`@`)
|
|
27
|
+
|
|
28
|
+
Other GTS spec [Reference Implementation](https://github.com/globaltypesystem/gts-spec/blob/main/README.md#9-reference-implementation-recommendations) recommended features support:
|
|
29
|
+
|
|
30
|
+
- [x] **In-memory entities registry** - simple GTS entities registry with optional GTS references validation on entity registration
|
|
31
|
+
- [x] **CLI** - command-line interface for all GTS operations
|
|
32
|
+
- [x] **Web server** - a non-production web-server with REST API for the operations processing and testing
|
|
33
|
+
- [x] **x-gts-ref** - to support special GTS entity reference annotation in schemas
|
|
34
|
+
- [ ] **YAML support** - to support YAML files (*.yml, *.yaml) as input files
|
|
35
|
+
- [ ] **TypeSpec support** - add [typespec.io](https://typespec.io/) files (*.tsp) support
|
|
36
|
+
- [ ] **UUID for instances** - to support UUID as ID in JSON instances
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
40
|
+
### Basic Operations
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { isValidGtsID, validateGtsID, parseGtsID, matchIDPattern, idToUUID } from '@globaltypesystem/gts-ts';
|
|
44
|
+
|
|
45
|
+
// OP#1 - ID Validation
|
|
46
|
+
if (isValidGtsID('gts.vendor.pkg.ns.type.v1~')) {
|
|
47
|
+
console.log('Valid GTS ID');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const result = validateGtsID('gts.vendor.pkg.ns.type.v1~');
|
|
51
|
+
if (result.valid) {
|
|
52
|
+
console.log(`Valid: ${result.id}`);
|
|
53
|
+
} else {
|
|
54
|
+
console.log(`Invalid: ${result.error}`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// OP#2 - ID Extraction
|
|
58
|
+
import { extractID } from '@globaltypesystem/gts-ts';
|
|
59
|
+
|
|
60
|
+
const content = {
|
|
61
|
+
gtsId: 'gts.vendor.pkg.ns.type.v1.0',
|
|
62
|
+
name: 'My Entity'
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const extracted = extractID(content);
|
|
66
|
+
console.log(`ID: ${extracted.id}`);
|
|
67
|
+
console.log(`Schema ID: ${extracted.schemaId}`);
|
|
68
|
+
|
|
69
|
+
// OP#3 - ID Parsing
|
|
70
|
+
const parsed = parseGtsID('gts.vendor.pkg.ns.type.v1~');
|
|
71
|
+
if (parsed.ok) {
|
|
72
|
+
for (const seg of parsed.segments) {
|
|
73
|
+
console.log(`Vendor: ${seg.vendor}, Package: ${seg.package}, Type: ${seg.type}, Version: v${seg.verMajor}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// OP#4 - Pattern Matching
|
|
78
|
+
const matchResult = matchIDPattern(
|
|
79
|
+
'gts.vendor.pkg.ns.type.v1.0',
|
|
80
|
+
'gts.vendor.pkg.*'
|
|
81
|
+
);
|
|
82
|
+
if (matchResult.match) {
|
|
83
|
+
console.log('Pattern matched!');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// OP#5 - UUID Generation
|
|
87
|
+
const uuidResult = idToUUID('gts.vendor.pkg.ns.type.v1~');
|
|
88
|
+
console.log(`UUID: ${uuidResult.uuid}`);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Using the GTS Store
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import { GTS } from '@globaltypesystem/gts-ts';
|
|
95
|
+
|
|
96
|
+
// Create a new store
|
|
97
|
+
const gts = new GTS();
|
|
98
|
+
|
|
99
|
+
// Register an entity
|
|
100
|
+
const entity = {
|
|
101
|
+
gtsId: 'gts.vendor.pkg.ns.type.v1.0',
|
|
102
|
+
name: 'My Entity'
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
gts.register(entity);
|
|
106
|
+
|
|
107
|
+
// OP#6 - Validate an instance
|
|
108
|
+
const validation = gts.validateInstance('gts.vendor.pkg.ns.type.v1.0');
|
|
109
|
+
if (validation.ok) {
|
|
110
|
+
console.log('Instance is valid');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// OP#7 - Resolve relationships
|
|
114
|
+
const relationships = gts.resolveRelationships('gts.vendor.pkg.ns.type.v1.0');
|
|
115
|
+
console.log(`Relationships: ${relationships.relationships}`);
|
|
116
|
+
console.log(`Broken references: ${relationships.brokenReferences}`);
|
|
117
|
+
|
|
118
|
+
// OP#8 - Check compatibility
|
|
119
|
+
const compatResult = gts.checkCompatibility(
|
|
120
|
+
'gts.vendor.pkg.ns.type.v1~',
|
|
121
|
+
'gts.vendor.pkg.ns.type.v2~',
|
|
122
|
+
'backward'
|
|
123
|
+
);
|
|
124
|
+
if (compatResult.compatible) {
|
|
125
|
+
console.log('Schemas are compatible');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// OP#9 - Cast instance to different version
|
|
129
|
+
const castResult = gts.castInstance(
|
|
130
|
+
'gts.vendor.pkg.ns.type.v1.0',
|
|
131
|
+
'gts.vendor.pkg.ns.type.v2~'
|
|
132
|
+
);
|
|
133
|
+
if (castResult.ok) {
|
|
134
|
+
console.log('Instance casted successfully');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// OP#10 - Query entities
|
|
138
|
+
const queryResult = gts.query('gts.vendor.pkg.*', 100);
|
|
139
|
+
console.log(`Found ${queryResult.count} entities`);
|
|
140
|
+
|
|
141
|
+
// OP#11 - Attribute access
|
|
142
|
+
const attr = gts.getAttribute('gts.vendor.pkg.ns.type.v1.0@name');
|
|
143
|
+
if (attr.resolved) {
|
|
144
|
+
console.log(`Attribute value: ${attr.value}`);
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Advanced Query Language
|
|
149
|
+
|
|
150
|
+
The query language supports complex expressions with AND, OR, and NOT operators:
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// Simple pattern matching
|
|
154
|
+
gts.query('gts.vendor.*');
|
|
155
|
+
|
|
156
|
+
// Complex queries with logical operators
|
|
157
|
+
gts.query('gts.vendor.* OR gts.other.*');
|
|
158
|
+
gts.query('gts.vendor.* AND NOT gts.vendor.test.*');
|
|
159
|
+
gts.query('(gts.vendor.* OR gts.other.*) AND gts.*.*.ns.*');
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## CLI Usage
|
|
163
|
+
|
|
164
|
+
The package includes a CLI tool for GTS operations:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# Install globally
|
|
168
|
+
npm install -g @globaltypesystem/gts-ts
|
|
169
|
+
|
|
170
|
+
# Or use locally with npx
|
|
171
|
+
npx gts
|
|
172
|
+
|
|
173
|
+
# Basic operations
|
|
174
|
+
gts validate-id -i gts.vendor.pkg.ns.type.v1~
|
|
175
|
+
gts parse-id -i gts.vendor.pkg.ns.type.v1.0
|
|
176
|
+
gts match-id -p "gts.vendor.pkg.*" -c gts.vendor.pkg.ns.type.v1.0
|
|
177
|
+
gts uuid -i gts.vendor.pkg.ns.type.v1~
|
|
178
|
+
|
|
179
|
+
# Operations with loaded entities
|
|
180
|
+
gts --path ./examples validate -i gts.vendor.pkg.ns.type.v1.0
|
|
181
|
+
gts --path ./examples relationships -i gts.vendor.pkg.ns.type.v1~
|
|
182
|
+
gts --path ./examples compatibility -o gts.vendor.pkg.ns.type.v1~ -n gts.vendor.pkg.ns.type.v2~
|
|
183
|
+
gts --path ./examples cast -f gts.vendor.pkg.ns.type.v1.0 -t gts.vendor.pkg.ns.type.v2~
|
|
184
|
+
gts --path ./examples query -e "gts.vendor.pkg.*" -l 10
|
|
185
|
+
gts --path ./examples attr -p gts.vendor.pkg.ns.type.v1.0@name
|
|
186
|
+
gts --path ./examples list -l 100
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Web Server
|
|
190
|
+
|
|
191
|
+
The package includes a non-production web server with REST API for testing and development:
|
|
192
|
+
|
|
193
|
+
### Building the Server
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# install dependencies
|
|
197
|
+
npm ci
|
|
198
|
+
|
|
199
|
+
# build the server
|
|
200
|
+
npm run build
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Starting the Server
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
# Using npm scripts
|
|
207
|
+
npm run server
|
|
208
|
+
|
|
209
|
+
# Using the CLI
|
|
210
|
+
gts server --host 127.0.0.1 --port 8000
|
|
211
|
+
|
|
212
|
+
# With preloaded entities
|
|
213
|
+
gts --path ./examples server --port 8001
|
|
214
|
+
|
|
215
|
+
# Using the dedicated server command
|
|
216
|
+
npx gts-server --host 127.0.0.1 --port 8000 --verbose 2
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### API Endpoints
|
|
220
|
+
|
|
221
|
+
#### Entity Management
|
|
222
|
+
- `GET /entities` - List all entities
|
|
223
|
+
- `GET /entities/:id` - Get specific entity
|
|
224
|
+
- `POST /entities` - Add new entity
|
|
225
|
+
- `POST /entities/bulk` - Add multiple entities
|
|
226
|
+
- `POST /schemas` - Add new schema
|
|
227
|
+
|
|
228
|
+
#### GTS Operations
|
|
229
|
+
- `GET /validate-id?id=<gts_id>` - Validate GTS ID (OP#1)
|
|
230
|
+
- `POST /extract-id` - Extract GTS ID from JSON (OP#2)
|
|
231
|
+
- `GET /parse-id?id=<gts_id>` - Parse GTS ID (OP#3)
|
|
232
|
+
- `GET /match-id-pattern?pattern=<pattern>&candidate=<id>` - Match pattern (OP#4)
|
|
233
|
+
- `GET /uuid?id=<gts_id>` - Generate UUID (OP#5)
|
|
234
|
+
- `POST /validate-instance` - Validate instance (OP#6)
|
|
235
|
+
- `GET /resolve-relationships?id=<gts_id>` - Resolve relationships (OP#7)
|
|
236
|
+
- `GET /compatibility?old=<id>&new=<id>&mode=<mode>` - Check compatibility (OP#8)
|
|
237
|
+
- `POST /cast` - Cast instance (OP#9)
|
|
238
|
+
- `GET /query?expr=<expression>&limit=<limit>` - Query entities (OP#10)
|
|
239
|
+
- `GET /attr?path=<path>` - Get attribute value (OP#11)
|
|
240
|
+
|
|
241
|
+
#### Other
|
|
242
|
+
- `GET /health` - Health check
|
|
243
|
+
- `GET /openapi` - OpenAPI specification
|
|
244
|
+
|
|
245
|
+
### Example Usage
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
# Health check
|
|
249
|
+
curl http://127.0.0.1:8000/health
|
|
250
|
+
|
|
251
|
+
# Validate a GTS ID
|
|
252
|
+
curl "http://127.0.0.1:8000/validate-id?id=gts.vendor.pkg.ns.type.v1~"
|
|
253
|
+
|
|
254
|
+
# Add a schema
|
|
255
|
+
curl -X POST http://127.0.0.1:8000/schemas \
|
|
256
|
+
-H "Content-Type: application/json" \
|
|
257
|
+
-d '{
|
|
258
|
+
"$$id": "gts.test.example.ns.person.v1~",
|
|
259
|
+
"type": "object",
|
|
260
|
+
"properties": {
|
|
261
|
+
"name": { "type": "string" },
|
|
262
|
+
"age": { "type": "number" }
|
|
263
|
+
},
|
|
264
|
+
"required": ["name"]
|
|
265
|
+
}'
|
|
266
|
+
|
|
267
|
+
# Query entities
|
|
268
|
+
curl "http://127.0.0.1:8000/query?expr=gts.test.*&limit=10"
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Development
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
# Install dependencies
|
|
275
|
+
npm install
|
|
276
|
+
|
|
277
|
+
# Build the project
|
|
278
|
+
npm run build
|
|
279
|
+
|
|
280
|
+
# Run tests
|
|
281
|
+
npm test
|
|
282
|
+
|
|
283
|
+
# Run linting
|
|
284
|
+
npm run lint
|
|
285
|
+
|
|
286
|
+
# Type checking
|
|
287
|
+
npm run typecheck
|
|
288
|
+
|
|
289
|
+
# Format code
|
|
290
|
+
npm run format
|
|
291
|
+
|
|
292
|
+
# Start development server
|
|
293
|
+
npm run server:dev
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## License
|
|
297
|
+
|
|
298
|
+
Apache License 2.0
|
package/dist/cast.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { CastResult } from './types';
|
|
2
|
+
import { GtsStore } from './store';
|
|
3
|
+
export declare class GtsCast {
|
|
4
|
+
static castInstance(store: GtsStore, fromId: string, toSchemaId: string): CastResult;
|
|
5
|
+
private static performCast;
|
|
6
|
+
private static getDefaultValue;
|
|
7
|
+
private static getDefaultForType;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=cast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cast.d.ts","sourceRoot":"","sources":["../src/cast.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAInC,qBAAa,OAAO;IAClB,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU;IAwFpF,OAAO,CAAC,MAAM,CAAC,WAAW;IAmD1B,OAAO,CAAC,MAAM,CAAC,eAAe;IAgB9B,OAAO,CAAC,MAAM,CAAC,iBAAiB;CAiBjC"}
|
package/dist/cast.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GtsCast = void 0;
|
|
4
|
+
const gts_1 = require("./gts");
|
|
5
|
+
const compatibility_1 = require("./compatibility");
|
|
6
|
+
class GtsCast {
|
|
7
|
+
static castInstance(store, fromId, toSchemaId) {
|
|
8
|
+
try {
|
|
9
|
+
const fromGtsId = gts_1.Gts.parseGtsID(fromId);
|
|
10
|
+
const fromEntity = store.get(fromGtsId.id);
|
|
11
|
+
if (!fromEntity) {
|
|
12
|
+
return {
|
|
13
|
+
ok: false,
|
|
14
|
+
fromId,
|
|
15
|
+
toId: toSchemaId,
|
|
16
|
+
error: `Instance not found: ${fromId}`,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
if (!fromEntity.schemaId) {
|
|
20
|
+
return {
|
|
21
|
+
ok: false,
|
|
22
|
+
fromId,
|
|
23
|
+
toId: toSchemaId,
|
|
24
|
+
error: `No schema found for instance: ${fromId}`,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const toGtsId = gts_1.Gts.parseGtsID(toSchemaId);
|
|
28
|
+
const toSchema = store.get(toGtsId.id);
|
|
29
|
+
if (!toSchema) {
|
|
30
|
+
return {
|
|
31
|
+
ok: false,
|
|
32
|
+
fromId,
|
|
33
|
+
toId: toSchemaId,
|
|
34
|
+
error: `Target schema not found: ${toSchemaId}`,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (!toSchema.isSchema) {
|
|
38
|
+
return {
|
|
39
|
+
ok: false,
|
|
40
|
+
fromId,
|
|
41
|
+
toId: toSchemaId,
|
|
42
|
+
error: `Target is not a schema: ${toSchemaId}`,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const fromSchemaEntity = store.get(fromEntity.schemaId);
|
|
46
|
+
if (!fromSchemaEntity) {
|
|
47
|
+
return {
|
|
48
|
+
ok: false,
|
|
49
|
+
fromId,
|
|
50
|
+
toId: toSchemaId,
|
|
51
|
+
error: `Source schema not found: ${fromEntity.schemaId}`,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const compatCheck = compatibility_1.GtsCompatibility.checkCompatibility(store, fromEntity.schemaId, toSchemaId, 'full');
|
|
55
|
+
if (!compatCheck.compatible) {
|
|
56
|
+
return {
|
|
57
|
+
ok: false,
|
|
58
|
+
fromId,
|
|
59
|
+
toId: toSchemaId,
|
|
60
|
+
error: `Schemas are not compatible: ${compatCheck.errors.join('; ')}`,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
const castedInstance = this.performCast(fromEntity.content, fromSchemaEntity.content, toSchema.content, toSchemaId);
|
|
64
|
+
return {
|
|
65
|
+
ok: true,
|
|
66
|
+
fromId,
|
|
67
|
+
toId: toSchemaId,
|
|
68
|
+
result: castedInstance,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
return {
|
|
73
|
+
ok: false,
|
|
74
|
+
fromId,
|
|
75
|
+
toId: toSchemaId,
|
|
76
|
+
error: error instanceof Error ? error.message : String(error),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
static performCast(instance, fromSchema, toSchema, toSchemaId) {
|
|
81
|
+
const result = { ...instance };
|
|
82
|
+
const fromSegments = gts_1.Gts.parseID(fromSchema['$$id'] || fromSchema['$id']).segments;
|
|
83
|
+
const toSegments = gts_1.Gts.parseID(toSchemaId).segments;
|
|
84
|
+
if (fromSegments.length > 0 && toSegments.length > 0) {
|
|
85
|
+
const fromVersion = `v${fromSegments[0].verMajor}.${fromSegments[0].verMinor ?? 0}`;
|
|
86
|
+
const toVersion = `v${toSegments[0].verMajor}.${toSegments[0].verMinor ?? 0}`;
|
|
87
|
+
if ('gtsId' in result) {
|
|
88
|
+
result.gtsId = result.gtsId.replace(fromVersion, toVersion);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if ('$schema' in result || '$$schema' in result) {
|
|
92
|
+
result['$schema'] = toSchemaId;
|
|
93
|
+
if ('$$schema' in result) {
|
|
94
|
+
result['$$schema'] = toSchemaId;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const toProps = toSchema.properties || {};
|
|
98
|
+
const toRequired = new Set(toSchema.required || []);
|
|
99
|
+
const filtered = {};
|
|
100
|
+
for (const [key, value] of Object.entries(result)) {
|
|
101
|
+
if (key in toProps || key === 'gtsId' || key === '$schema' || key === '$$schema') {
|
|
102
|
+
filtered[key] = value;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
for (const prop of toRequired) {
|
|
106
|
+
if (!(prop in filtered)) {
|
|
107
|
+
const propSchema = toProps[prop];
|
|
108
|
+
if (propSchema) {
|
|
109
|
+
filtered[prop] = this.getDefaultValue(propSchema);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Also add properties with default values that aren't required
|
|
114
|
+
for (const [propName, propSchema] of Object.entries(toProps)) {
|
|
115
|
+
if (!(propName in filtered) && propSchema && typeof propSchema === 'object' && 'default' in propSchema) {
|
|
116
|
+
filtered[propName] = propSchema.default;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return filtered;
|
|
120
|
+
}
|
|
121
|
+
static getDefaultValue(schema) {
|
|
122
|
+
if ('default' in schema) {
|
|
123
|
+
return schema.default;
|
|
124
|
+
}
|
|
125
|
+
const type = schema.type;
|
|
126
|
+
if (Array.isArray(type)) {
|
|
127
|
+
if (type.includes('null')) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
return this.getDefaultForType(type[0]);
|
|
131
|
+
}
|
|
132
|
+
return this.getDefaultForType(type);
|
|
133
|
+
}
|
|
134
|
+
static getDefaultForType(type) {
|
|
135
|
+
switch (type) {
|
|
136
|
+
case 'string':
|
|
137
|
+
return '';
|
|
138
|
+
case 'number':
|
|
139
|
+
case 'integer':
|
|
140
|
+
return 0;
|
|
141
|
+
case 'boolean':
|
|
142
|
+
return false;
|
|
143
|
+
case 'array':
|
|
144
|
+
return [];
|
|
145
|
+
case 'object':
|
|
146
|
+
return {};
|
|
147
|
+
default:
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
exports.GtsCast = GtsCast;
|
|
153
|
+
//# sourceMappingURL=cast.js.map
|
package/dist/cast.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cast.js","sourceRoot":"","sources":["../src/cast.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|