@takeshape/schema 8.37.0 → 8.38.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 (43) hide show
  1. package/es/flatten-templates.js +26 -0
  2. package/es/index.js +2 -1
  3. package/es/layers/layers.js +1 -1
  4. package/es/layers/refs.js +1 -1
  5. package/es/refs.js +74 -2
  6. package/es/schema-util.js +28 -17
  7. package/es/template-shapes/index.js +35 -0
  8. package/es/template-shapes/templates.js +379 -0
  9. package/es/template-shapes/types.js +1 -0
  10. package/es/template-shapes/where.js +501 -0
  11. package/es/validate.js +2 -2
  12. package/lib/flatten-templates.d.ts +3 -0
  13. package/lib/flatten-templates.d.ts.map +1 -0
  14. package/lib/flatten-templates.js +39 -0
  15. package/lib/index.d.ts +1 -0
  16. package/lib/index.d.ts.map +1 -1
  17. package/lib/index.js +14 -0
  18. package/lib/layers/layers.js +3 -3
  19. package/lib/layers/refs.js +2 -2
  20. package/lib/refs.d.ts +26 -1
  21. package/lib/refs.d.ts.map +1 -1
  22. package/lib/refs.js +94 -11
  23. package/lib/schema-util.d.ts +7 -6
  24. package/lib/schema-util.d.ts.map +1 -1
  25. package/lib/schema-util.js +41 -29
  26. package/lib/template-shapes/index.d.ts +8 -0
  27. package/lib/template-shapes/index.d.ts.map +1 -0
  28. package/lib/template-shapes/index.js +46 -0
  29. package/lib/template-shapes/templates.d.ts +29 -0
  30. package/lib/template-shapes/templates.d.ts.map +1 -0
  31. package/lib/template-shapes/templates.js +427 -0
  32. package/lib/template-shapes/types.d.ts +10 -0
  33. package/lib/template-shapes/types.d.ts.map +1 -0
  34. package/lib/template-shapes/types.js +5 -0
  35. package/lib/template-shapes/where.d.ts +39 -0
  36. package/lib/template-shapes/where.d.ts.map +1 -0
  37. package/lib/template-shapes/where.js +534 -0
  38. package/lib/validate.js +1 -1
  39. package/package.json +4 -4
  40. package/es/template-shapes.js +0 -79
  41. package/lib/template-shapes.d.ts +0 -32
  42. package/lib/template-shapes.d.ts.map +0 -1
  43. package/lib/template-shapes.js +0 -101
@@ -0,0 +1,501 @@
1
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
+
3
+ import { pascalCase, isDefined } from '@takeshape/util';
4
+ import isEqual from 'lodash/isEqual';
5
+ import get from 'lodash/get';
6
+ import unset from 'lodash/unset';
7
+ import isFunction from 'lodash/isFunction';
8
+ import { createSchemaPropertyList, createShape, getAllRefsInShapes, getShapeById, isIndexedRemoteShape } from '../schema-util';
9
+ import { workflowsEnabled } from '../api-version';
10
+ import { followRef, getRefOrItemsRef, hasRefProperty, hasResolvableRef, refItemToShapeName } from '../refs';
11
+ import { enumerateOneOfKeys, isUnionSchema } from '../unions';
12
+ import { isObjectSchema } from '../types';
13
+ export const MAX_RELATIONSHIP_DEPTH = 1;
14
+ export const exceededRelationshipDepth = (depth = 0) => depth >= MAX_RELATIONSHIP_DEPTH;
15
+
16
+ class ShapeCache {
17
+ constructor() {
18
+ _defineProperty(this, "thunks", new Map());
19
+
20
+ _defineProperty(this, "unresolved", new Set());
21
+ }
22
+
23
+ has(shapeName) {
24
+ return this.thunks.has(shapeName);
25
+ }
26
+
27
+ set(shapeName, thunk) {
28
+ this.thunks.set(shapeName, thunk);
29
+
30
+ if (isFunction(thunk)) {
31
+ this.unresolved.add(shapeName);
32
+ }
33
+ }
34
+
35
+ resolveAll() {
36
+ while (this.unresolved.size) {
37
+ const shapeName = this.unresolved.values().next().value;
38
+ const thunk = this.thunks.get(shapeName);
39
+
40
+ if (isFunction(thunk)) {
41
+ this.thunks.set(shapeName, thunk());
42
+ this.unresolved.delete(shapeName);
43
+ }
44
+ }
45
+
46
+ const result = {};
47
+
48
+ for (const [shapeName, shape] of this.thunks) {
49
+ result[shapeName] = shape;
50
+ }
51
+
52
+ return result;
53
+ }
54
+
55
+ }
56
+
57
+ export const fieldTypeComparison = {
58
+ id: {
59
+ comparators: ['eq', 'in'],
60
+ type: 'string'
61
+ },
62
+ boolean: {
63
+ comparators: ['eq'],
64
+ type: 'boolean'
65
+ },
66
+ string: {
67
+ comparators: ['eq', 'in', 'match', 'regexp'],
68
+ type: 'string'
69
+ },
70
+ date: {
71
+ comparators: ['eq', 'lt', 'lte', 'gt', 'gte'],
72
+ type: 'string'
73
+ },
74
+ number: {
75
+ comparators: ['eq', 'lt', 'lte', 'gt', 'gte', 'in'],
76
+ type: 'number'
77
+ },
78
+ integer: {
79
+ comparators: ['eq', 'lt', 'lte', 'gt', 'gte', 'in'],
80
+ type: 'integer'
81
+ },
82
+ workflow: {
83
+ comparators: ['eq', 'lt', 'lte', 'gt', 'gte', 'in'],
84
+ type: 'string'
85
+ },
86
+ draftjs: {
87
+ comparators: ['match'],
88
+ type: 'string'
89
+ },
90
+ mdx: {
91
+ comparators: ['match'],
92
+ type: 'string'
93
+ }
94
+ };
95
+ export const comparatorDescriptions = {
96
+ eq: 'Exact match',
97
+ gt: 'Greater than',
98
+ gte: 'Greater than or equal',
99
+ lt: 'Less than',
100
+ lte: 'Less than or equal',
101
+ in: 'Array of possible exact match values.',
102
+ match: 'Full text searching with fuzzy matching.',
103
+ regexp: 'Regular expression string matching. Use of * wildcards could degrade performance.'
104
+ };
105
+ export const booleanOperators = ['AND', 'OR', 'NOT'];
106
+ export const boolOpDescriptionMap = {
107
+ AND: 'AND takes an array of conditions that must appear in the matching results. Nested boolean operators can be used to create complex filters.',
108
+ OR: 'OR takes an array of conditions that should appear in the matching results. Nested boolean operators can be used to create complex filters.',
109
+ NOT: 'NOT takes a single condition that must not appear in the matching results.'
110
+ };
111
+
112
+ const getConflictingProperties = (projectSchema, shapes) => {
113
+ let conflicts = [];
114
+ const allProps = {};
115
+
116
+ for (const shape of Object.values(shapes)) {
117
+ const shapeConflicts = createSchemaPropertyList(projectSchema, shape.schema).filterBy(([name, prop]) => name in allProps && (allProps[name].type !== prop.type || !isEqual(get(allProps, [name, '@relationship', 'shapeIds']), get(prop, ['@relationship', 'shapeIds'])))).getNames();
118
+ conflicts = conflicts.concat(shapeConflicts);
119
+
120
+ if (isObjectSchema(shape.schema)) {
121
+ Object.assign(allProps, shape.schema.properties);
122
+ }
123
+ }
124
+
125
+ return conflicts;
126
+ };
127
+
128
+ export function getFieldTypeComparison(fieldType) {
129
+ const comparison = fieldTypeComparison[fieldType];
130
+
131
+ if (!comparison) {
132
+ return undefined;
133
+ }
134
+
135
+ const {
136
+ comparators,
137
+ type
138
+ } = comparison;
139
+ const result = {};
140
+
141
+ for (const op of comparators) {
142
+ const description = comparatorDescriptions[op];
143
+ result[op] = op === 'in' ? {
144
+ type: 'array',
145
+ items: {
146
+ type
147
+ },
148
+ description
149
+ } : {
150
+ description,
151
+ type
152
+ };
153
+ }
154
+
155
+ return result;
156
+ }
157
+
158
+ function isId(name) {
159
+ return name === '_id' || name === '_contentTypeId' || name === '_shapeId';
160
+ }
161
+
162
+ function isNonRelationshipRef(prop) {
163
+ return Boolean(hasRefProperty(prop) && !prop['@relationship']);
164
+ }
165
+
166
+ function getPropType(projectSchema, name, prop) {
167
+ if (prop['@workflow']) {
168
+ return 'workflow';
169
+ }
170
+
171
+ if (prop['@tag'] === 'draftjs') {
172
+ return 'draftjs';
173
+ }
174
+
175
+ if (prop['@tag'] === 'mdx') {
176
+ return 'mdx';
177
+ }
178
+
179
+ if (prop.format === 'date-time') {
180
+ return 'date';
181
+ }
182
+
183
+ if (isId(name)) {
184
+ return 'id';
185
+ }
186
+
187
+ if (isNonRelationshipRef(prop)) {
188
+ const followed = followRef(projectSchema, prop);
189
+
190
+ if (followed.enum) {
191
+ return 'string';
192
+ }
193
+
194
+ return 'object';
195
+ }
196
+
197
+ return prop.type;
198
+ }
199
+
200
+ function getRelatedShapeNames(prop, projectSchema) {
201
+ var _prop$Relationship;
202
+
203
+ const names = (_prop$Relationship = prop['@relationship']) === null || _prop$Relationship === void 0 ? void 0 : _prop$Relationship.shapeIds.map(id => {
204
+ const shape = getShapeById(projectSchema, id);
205
+ return pascalCase(shape ? shape.name : '');
206
+ }).sort().join('');
207
+
208
+ if (!names) {
209
+ throw new Error(`Relationship property ${prop.title} is missing related shapes`);
210
+ }
211
+
212
+ return names;
213
+ }
214
+
215
+ function joinShapeNames(shapes) {
216
+ return shapes.sort().join('');
217
+ }
218
+
219
+ function getTypeName(name, prop, shapeName, context) {
220
+ const {
221
+ projectSchema,
222
+ relationshipDepth,
223
+ conflictingProperties
224
+ } = context;
225
+ let type = getPropType(projectSchema, name, prop);
226
+
227
+ if (isId(name)) {
228
+ return `TSWhereID`;
229
+ }
230
+
231
+ if (prop['@relationship']) {
232
+ const shapeNames = getRelatedShapeNames(prop, projectSchema);
233
+ return `TSWhere${shapeNames}Relationship`;
234
+ }
235
+
236
+ if (isUnionSchema(prop)) {
237
+ if (prop.oneOf.length > 1) {
238
+ const shapeNames = joinShapeNames(enumerateOneOfKeys(projectSchema, prop.oneOf).map(child => child.shapeName));
239
+ return `TSWhere${shapeNames}Union`;
240
+ }
241
+
242
+ type = 'object';
243
+ prop = prop.oneOf[0];
244
+ }
245
+
246
+ if (type === 'object' || type === 'array') {
247
+ const prefix = `TS${relationshipDepth >= MAX_RELATIONSHIP_DEPTH ? 'Shallow' : ''}Where`;
248
+ const fieldName = `${conflictingProperties.includes(name) ? '_' : ''}${pascalCase(name)}`;
249
+ const refItem = getRefOrItemsRef(projectSchema, prop);
250
+ const suffix = refItem ? refItemToShapeName(refItem) : `${shapeName}${fieldName}`;
251
+ return `${prefix}${suffix}`;
252
+ }
253
+
254
+ return `TSWhere${pascalCase(type)}`;
255
+ }
256
+
257
+ function skipField(name, prop, projectSchema, exceededRelationshipDepth) {
258
+ return Boolean(prop['@user'] || prop['@sensitive'] || prop['@resolver'] || prop['@relationship'] && exceededRelationshipDepth || (name === '_enabled' || name === '_enabledAt') && workflowsEnabled(projectSchema.apiVersion));
259
+ }
260
+
261
+ export function getFields(typeName, shapes, context) {
262
+ const {
263
+ shapeCache,
264
+ relationshipDepth,
265
+ booleanOperators,
266
+ projectSchema
267
+ } = context;
268
+ const result = {};
269
+ const tooDeep = exceededRelationshipDepth(relationshipDepth);
270
+
271
+ for (const shape of shapes) {
272
+ const nodes = createSchemaPropertyList(projectSchema, shape.schema).filterBy(([name, property]) => !skipField(name, property, projectSchema, tooDeep)).getNodes();
273
+
274
+ for (const [name, property] of nodes) {
275
+ Object.assign(result, getPropertyComparisonType(name, property, shape.name, context));
276
+ }
277
+ }
278
+
279
+ return tooDeep || booleanOperators === false ? result : Object.assign(result, getBooleanOperatorTypes(result, typeName, shapeCache));
280
+ }
281
+
282
+ function getBooleanOperatorTypes(fields, typeName, shapeCache) {
283
+ const result = {};
284
+
285
+ for (const op of booleanOperators) {
286
+ const name = `${typeName}${pascalCase(op)}Operator`;
287
+
288
+ if (!shapeCache.has(name)) {
289
+ shapeCache.set(name, () => createShape(name, {
290
+ type: 'object',
291
+ properties: { ...fields,
292
+ ...(op !== 'NOT' && getBooleanOperatorTypes(fields, typeName, shapeCache))
293
+ }
294
+ }, {
295
+ description: boolOpDescriptionMap[op]
296
+ }));
297
+ }
298
+
299
+ const refSchema = {
300
+ '@ref': `local:${name}`
301
+ };
302
+ result[op] = op === 'NOT' ? refSchema : {
303
+ type: 'array',
304
+ items: refSchema
305
+ };
306
+ }
307
+
308
+ return result;
309
+ }
310
+
311
+ export function getPropertyComparisonType(name, prop, shapeName, context) {
312
+ const {
313
+ shapeCache,
314
+ projectSchema,
315
+ relationshipDepth,
316
+ conflictingProperties
317
+ } = context;
318
+
319
+ if (skipField(name, prop, projectSchema, exceededRelationshipDepth(relationshipDepth))) {
320
+ return undefined;
321
+ }
322
+
323
+ const fieldType = getPropType(projectSchema, name, prop) ?? 'string';
324
+ const typeName = getTypeName(name, prop, shapeName, context);
325
+
326
+ if (hasRefProperty(prop.items ?? prop)) {
327
+ if (!hasResolvableRef(projectSchema, prop.items ?? prop)) {
328
+ return undefined;
329
+ }
330
+
331
+ if (prop.items) {
332
+ prop = { ...prop,
333
+ items: followRef(projectSchema, prop.items)
334
+ };
335
+ } else {
336
+ prop = followRef(projectSchema, prop);
337
+ }
338
+ }
339
+
340
+ if (!shapeCache.has(typeName)) {
341
+ shapeCache.set(typeName, () => {
342
+ var _prop$items;
343
+
344
+ let props;
345
+ const propOrItems = prop.items ?? prop;
346
+
347
+ if (isId(name)) {
348
+ props = getFieldTypeComparison('id');
349
+ } else if (prop['@relationship']) {
350
+ const shapes = prop['@relationship'].shapeIds.map(id => getShapeById(projectSchema, id)).filter(isDefined);
351
+ props = getFields(typeName, shapes, { ...context,
352
+ conflictingProperties: getConflictingProperties(context.projectSchema, shapes),
353
+ relationshipDepth: relationshipDepth + 1
354
+ });
355
+ } else if (isUnionSchema(propOrItems)) {
356
+ const shapes = enumerateOneOfKeys(projectSchema, propOrItems.oneOf).map(option => projectSchema.shapes[option.shapeName]);
357
+ props = getFields(typeName, shapes, { ...context,
358
+ conflictingProperties: getConflictingProperties(context.projectSchema, shapes),
359
+ relationshipDepth,
360
+ booleanOperators: false
361
+ });
362
+ } else if (fieldType === 'object' || fieldType === 'array' && ((_prop$items = prop.items) === null || _prop$items === void 0 ? void 0 : _prop$items.type) === 'object') {
363
+ var _prop$items2;
364
+
365
+ const properties = ((_prop$items2 = prop.items) === null || _prop$items2 === void 0 ? void 0 : _prop$items2.properties) ?? prop.properties;
366
+
367
+ if (properties) {
368
+ for (const propName of Object.keys(properties)) {
369
+ props = { ...props,
370
+ ...getPropertyComparisonType(propName, properties[propName], shapeName, context)
371
+ };
372
+ }
373
+ }
374
+ } else {
375
+ var _prop$items3;
376
+
377
+ // Treat non-object arrays as their base type
378
+ let type;
379
+
380
+ if (typeof ((_prop$items3 = prop.items) === null || _prop$items3 === void 0 ? void 0 : _prop$items3.type) === 'string') {
381
+ type = prop.items.type;
382
+ } else {
383
+ type = fieldType;
384
+ }
385
+
386
+ props = getFieldTypeComparison(type);
387
+ }
388
+
389
+ return createShape(typeName, {
390
+ type: 'object',
391
+ properties: props ?? {}
392
+ });
393
+ });
394
+ }
395
+
396
+ if (shapeCache.has(typeName)) {
397
+ const fieldName = `${conflictingProperties.includes(name) ? `${shapeName}_` : ''}${name}`;
398
+ return {
399
+ [fieldName]: {
400
+ '@ref': `local:${typeName}`
401
+ }
402
+ };
403
+ }
404
+ }
405
+
406
+ function findEmpty(shapes) {
407
+ const empty = new Set();
408
+
409
+ for (const [shapeName, shape] of Object.entries(shapes)) {
410
+ if (isObjectSchema(shape.schema) && Object.keys(shape.schema.properties).length === 0) {
411
+ empty.add(shapeName);
412
+ }
413
+ }
414
+
415
+ return empty;
416
+ }
417
+
418
+ function getRefSummary(shapes) {
419
+ const result = {};
420
+
421
+ for (const ref of getAllRefsInShapes({
422
+ shapes,
423
+ services: {}
424
+ })) {
425
+ const path = ref.path.slice(1, ref.path.length - 1);
426
+
427
+ if (result[ref.typeName]) {
428
+ result[ref.typeName].push(path);
429
+ } else {
430
+ result[ref.typeName] = [path];
431
+ }
432
+ }
433
+
434
+ return result;
435
+ }
436
+
437
+ function pruneEmpty(shapes) {
438
+ let toPrune = findEmpty(shapes);
439
+
440
+ if (toPrune.size) {
441
+ const refSummary = getRefSummary(shapes);
442
+
443
+ while (toPrune.size) {
444
+ for (const shapeName of toPrune) {
445
+ unset(shapes, shapeName);
446
+
447
+ for (const path of refSummary[shapeName] ?? []) {
448
+ unset(shapes, path);
449
+ }
450
+ }
451
+
452
+ toPrune = findEmpty(shapes);
453
+ }
454
+ }
455
+
456
+ return shapes;
457
+ }
458
+
459
+ export function getWhereShape(projectSchema, shapes) {
460
+ const isManyContentTypes = shapes.length > 1;
461
+ const shapeName = isManyContentTypes ? 'TSWhereInput' : `TSWhere${pascalCase(shapes[0].name)}Input`;
462
+ const shapeCache = new ShapeCache();
463
+ const conflictingProperties = getConflictingProperties(projectSchema, shapes);
464
+ const fields = getFields(shapeName, shapes, {
465
+ projectSchema,
466
+ shapeCache,
467
+ conflictingProperties,
468
+ relationshipDepth: 0
469
+ });
470
+ return {
471
+ shapeName,
472
+ dependencies: pruneEmpty({
473
+ [shapeName]: createShape(shapeName, {
474
+ type: 'object',
475
+ properties: { ...fields,
476
+ ...(isManyContentTypes && getBooleanOperatorTypes(fields, shapeName, shapeCache))
477
+ }
478
+ }),
479
+ ...shapeCache.resolveAll()
480
+ })
481
+ };
482
+ }
483
+ export function getWhereSearchArg(projectSchema, shapes) {
484
+ const {
485
+ shapeName,
486
+ dependencies
487
+ } = getWhereShape(projectSchema, shapes.filter(s => s.model !== undefined || isIndexedRemoteShape(projectSchema, s)));
488
+ const schema = {
489
+ type: 'object',
490
+ properties: {
491
+ where: {
492
+ '@ref': `local:${shapeName}`,
493
+ description: 'The where clause uses the boolean AND, OR, and NOT parameters to construct complex filters based on the values of your fields. It applies an implicit AND to all the top-level keys. To avoid this, use a single OR or NOT key as the only top-level key.'
494
+ }
495
+ }
496
+ };
497
+ return {
498
+ schema,
499
+ dependencies
500
+ };
501
+ }
package/es/validate.js CHANGED
@@ -11,9 +11,9 @@ import { allProjectSchemas } from './schemas';
11
11
  import authSchemas from './schemas/auth-schemas.json';
12
12
  import { getAllNamespaceShapes, visitShapeProperties, getAllRefsInShapes } from './schema-util';
13
13
  import { builtInShapes } from './builtin-schema';
14
- import { isValidTemplate, parseReturnShape } from './template-shapes';
14
+ import { isValidTemplate } from './template-shapes';
15
15
  import { isBasicResolver, isComposeResolver } from './types/utils';
16
- import { refItemToAtRef, refItemToShapeName } from './refs';
16
+ import { refItemToAtRef, refItemToShapeName, parseReturnShape } from './refs';
17
17
  import { scalars } from './scalars';
18
18
  import { enumerateOneOfKeys, isUnionSchema } from './unions';
19
19
  import { isEnumLikeSchema } from './enum';
@@ -0,0 +1,3 @@
1
+ import { ProjectSchema } from './project-schema';
2
+ export declare function flattenTemplates(projectSchema: ProjectSchema): ProjectSchema;
3
+ //# sourceMappingURL=flatten-templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flatten-templates.d.ts","sourceRoot":"","sources":["../../src/flatten-templates.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAK/C,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,aAAa,GAAG,aAAa,CAgB5E"}
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.flattenTemplates = flattenTemplates;
7
+
8
+ var _templateShapes = require("./template-shapes");
9
+
10
+ var _schemaUtil = require("./schema-util");
11
+
12
+ var _set = _interopRequireDefault(require("lodash/set"));
13
+
14
+ var _util = require("@takeshape/util");
15
+
16
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
+
18
+ function flattenTemplates(projectSchema) {
19
+ const templateRefs = (0, _schemaUtil.getAllRefs)(projectSchema, ref => Boolean(ref.template));
20
+
21
+ if (!templateRefs.length) {
22
+ return projectSchema;
23
+ }
24
+
25
+ const newSchema = (0, _util.deepClone)(projectSchema);
26
+
27
+ for (const ref of templateRefs) {
28
+ if (ref.template && (0, _templateShapes.isValidTemplate)(ref.template)) {
29
+ const {
30
+ shapeName,
31
+ dependencies
32
+ } = (0, _templateShapes.resolveTemplate)(projectSchema, ref.template, ref.typeName);
33
+ (0, _set.default)(newSchema, ref.path, shapeName);
34
+ Object.assign(newSchema.shapes, dependencies);
35
+ }
36
+ }
37
+
38
+ return newSchema;
39
+ }
package/lib/index.d.ts CHANGED
@@ -24,4 +24,5 @@ export * from './enum';
24
24
  export * from './patterns';
25
25
  export * from './types/types';
26
26
  export * from './types/utils';
27
+ export * from './flatten-templates';
27
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAC,mBAAmB,EAAE,6BAA6B,EAAC,MAAM,mBAAmB,CAAC;AAE1F,YAAY,EAAC,IAAI,EAAC,MAAM,eAAe,CAAC;AACxC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAC/C,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAC,mBAAmB,EAAE,6BAA6B,EAAC,MAAM,mBAAmB,CAAC;AAE1F,YAAY,EAAC,IAAI,EAAC,MAAM,eAAe,CAAC;AACxC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAC/C,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC"}
package/lib/index.js CHANGED
@@ -333,4 +333,18 @@ Object.keys(_utils).forEach(function (key) {
333
333
  return _utils[key];
334
334
  }
335
335
  });
336
+ });
337
+
338
+ var _flattenTemplates = require("./flatten-templates");
339
+
340
+ Object.keys(_flattenTemplates).forEach(function (key) {
341
+ if (key === "default" || key === "__esModule") return;
342
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
343
+ if (key in exports && exports[key] === _flattenTemplates[key]) return;
344
+ Object.defineProperty(exports, key, {
345
+ enumerable: true,
346
+ get: function () {
347
+ return _flattenTemplates[key];
348
+ }
349
+ });
336
350
  });
@@ -25,7 +25,7 @@ var _visitor = require("./visitor");
25
25
 
26
26
  var _set = _interopRequireDefault(require("lodash/set"));
27
27
 
28
- var _templateShapes = require("../template-shapes");
28
+ var _refs2 = require("../refs");
29
29
 
30
30
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
31
31
 
@@ -281,7 +281,7 @@ function rewriteLayerId(localShapes, layerId, query) {
281
281
 
282
282
  if (query.args) {
283
283
  if (typeof query.args === 'string') {
284
- const [argsLayerId, shapeName] = (0, _refs.splitAtRef)((0, _templateShapes.parseTemplateShape)(query.args).shapeName);
284
+ const [argsLayerId, shapeName] = (0, _refs.splitAtRef)((0, _refs2.parseTemplateShape)(query.args).shapeName);
285
285
 
286
286
  if (argsLayerId === 'local' && !localShapes[shapeName]) {
287
287
  newQuery.args = `${layerId}:${shapeName}`;
@@ -292,7 +292,7 @@ function rewriteLayerId(localShapes, layerId, query) {
292
292
  }
293
293
 
294
294
  if (typeof query.shape === 'string') {
295
- const [argsLayerId, shapeName] = (0, _refs.splitAtRef)((0, _templateShapes.parseTemplateShape)(query.shape).shapeName);
295
+ const [argsLayerId, shapeName] = (0, _refs.splitAtRef)((0, _refs2.parseTemplateShape)(query.shape).shapeName);
296
296
 
297
297
  if (argsLayerId === 'local' && !localShapes[shapeName]) {
298
298
  newQuery.shape = `${layerId}:${shapeName}`;
@@ -23,7 +23,7 @@ exports.splitAtRef = splitAtRef;
23
23
 
24
24
  var _typeUtils = require("./type-utils");
25
25
 
26
- var _templateShapes = require("../template-shapes");
26
+ var _refs = require("../refs");
27
27
 
28
28
  var _assign = _interopRequireDefault(require("lodash/fp/assign"));
29
29
 
@@ -47,7 +47,7 @@ function refExpressionToRefItem(refExpression) {
47
47
  const {
48
48
  shapeName,
49
49
  template
50
- } = (0, _templateShapes.parseTemplateShape)(refExpression);
50
+ } = (0, _refs.parseTemplateShape)(refExpression);
51
51
  return atRefToRefItem(shapeName, template);
52
52
  }
53
53
  /**
package/lib/refs.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  /// <reference types="lodash" />
2
- import type { SchemaPath, SchemaWithRef, ProjectSchemaV3X } from './types/types';
2
+ import type { SchemaPath, SchemaWithRef, ProjectSchemaV3X } from './types';
3
3
  import type { PropertySchema, Shape, ShapeSchema } from './project-schema';
4
4
  import type { Maybe } from '@takeshape/util';
5
+ import { ReturnShape } from './project-schema';
5
6
  export declare type ServicesContext = Pick<ProjectSchemaV3X, 'services'>;
6
7
  export declare type ServicesShapesContext = Pick<ProjectSchemaV3X, 'services' | 'shapes'>;
7
8
  /**
@@ -22,6 +23,30 @@ export interface RefItem {
22
23
  export interface RefItemWithPath extends RefItem {
23
24
  path: SchemaPath;
24
25
  }
26
+ /**
27
+ * Parse a template like `PaginatedList<Post>` and return both the template and the shape name.
28
+ */
29
+ export declare function parseTemplateShape(shapeExpression: string): {
30
+ template: string | undefined;
31
+ shapeName: string;
32
+ };
33
+ export interface ParsedReturnShape {
34
+ isArray: boolean;
35
+ template?: string;
36
+ shapeName: string;
37
+ ref?: RefItem;
38
+ }
39
+ export declare function parseReturnShape(projectSchema: ServicesContext, shape: ReturnShape): ParsedReturnShape;
40
+ /**
41
+ * Create a template string like `PaginatedList<Post>` from a template and shape name.
42
+ */
43
+ export declare function createTemplateShapeName(template: string, shapeName: string): string;
44
+ /**
45
+ * If the string is a template like `PaginatedList<Post>`, return the shape name,
46
+ * in this case `Post`. Otherwise return the input.
47
+ */
48
+ export declare const untemplate: (input: string) => string;
49
+ export declare function getFlattenedTemplateShapeName(shapeName: string, template?: string): string;
25
50
  export declare function $refToAtRef($ref: string, service: string, namespace?: string): string;
26
51
  export declare function refSchemaToPath(context: ServicesContext, refSchema: SchemaWithRef): string[];
27
52
  /**