@takeshape/schema 11.89.0 → 11.92.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 (49) hide show
  1. package/dist/agents.d.ts +7 -0
  2. package/dist/agents.js +7 -0
  3. package/dist/builtin-schema.js +3 -1
  4. package/dist/flatten-templates.js +1 -1
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.js +1 -0
  7. package/dist/interfaces.d.ts +4 -2
  8. package/dist/interfaces.js +6 -5
  9. package/dist/migration/to/v3.34.0.js +2 -7
  10. package/dist/models/runtime-schema.js +7 -7
  11. package/dist/models/shape.d.ts +1 -0
  12. package/dist/models/shape.js +5 -2
  13. package/dist/project-schema/latest.d.ts +32 -12
  14. package/dist/project-schema/v3.48.0.d.ts +32 -12
  15. package/dist/project-schema/v3.49.0.d.ts +32 -12
  16. package/dist/project-schema/v3.50.0.d.ts +32 -12
  17. package/dist/project-schema/v3.51.0.d.ts +32 -12
  18. package/dist/project-schema/v3.52.0.d.ts +32 -12
  19. package/dist/project-schema/v3.53.0.d.ts +32 -12
  20. package/dist/project-schema/v3.54.0.d.ts +32 -12
  21. package/dist/project-schema/v3.55.0.d.ts +32 -12
  22. package/dist/refs.d.ts +30 -51
  23. package/dist/refs.js +101 -137
  24. package/dist/relationships.d.ts +1 -1
  25. package/dist/relationships.js +22 -31
  26. package/dist/schema-util.d.ts +4 -16
  27. package/dist/schema-util.js +12 -45
  28. package/dist/schemas/project-schema/experimental.json +107 -56
  29. package/dist/service-dependencies.js +9 -9
  30. package/dist/template-shapes/templates.d.ts +10 -10
  31. package/dist/template-shapes/templates.js +6 -9
  32. package/dist/template-shapes/where.js +9 -11
  33. package/dist/types/types.d.ts +0 -14
  34. package/dist/types/types.js +0 -8
  35. package/dist/types/utils.d.ts +2 -8
  36. package/dist/types/utils.js +1 -14
  37. package/dist/unions.js +2 -2
  38. package/dist/util/expressions.d.ts +13 -2
  39. package/dist/util/expressions.js +32 -0
  40. package/dist/util/form-config.js +1 -1
  41. package/dist/util/get-conflicting-properties.js +2 -2
  42. package/dist/util/has-arg.js +2 -2
  43. package/dist/util/is-asset-property.d.ts +3 -0
  44. package/dist/util/is-asset-property.js +11 -0
  45. package/dist/util/merge.js +1 -1
  46. package/dist/validate/validate.js +39 -20
  47. package/examples/latest/agent-schema.json +4 -2
  48. package/examples/source/agent-schema.json +4 -2
  49. package/package.json +6 -5
@@ -105,20 +105,6 @@ export type ServiceConfigUpdate = SetRequired<PartialDeep<ServiceConfigWithNullS
105
105
  export type LatestProjectSchemaWithServices = {
106
106
  services: ServiceMapJSON;
107
107
  } & ProjectSchemaJSON;
108
- /**
109
- * Types of refs
110
- */
111
- export declare enum RefType {
112
- '@ref' = "@ref",
113
- $ref = "$ref"
114
- }
115
- /**
116
- * Stub of a PropertySchema that may contain a `$ref` or `@ref`.
117
- */
118
- export type RefSchemaStub = {
119
- items?: RefSchemaStub;
120
- } & Pick<PropertySchema, RefType>;
121
- export type SchemaWithRef = PropertySchema | RefSchemaStub;
122
108
  /**
123
109
  * Types of args
124
110
  */
@@ -1,13 +1,5 @@
1
1
  export const projectSchemaImportOptionalProps = ['projectId', 'locales', 'defaultLocale', 'author'];
2
2
  export const legacyProjectSchemaImportOptionalProps = ['created', 'updated', 'version', 'dataKey'];
3
- /**
4
- * Types of refs
5
- */
6
- export var RefType;
7
- (function (RefType) {
8
- RefType["@ref"] = "@ref";
9
- RefType["$ref"] = "$ref";
10
- })(RefType || (RefType = {}));
11
3
  /**
12
4
  * Types of args
13
5
  */
@@ -1,7 +1,7 @@
1
1
  import type { Maybe } from '@takeshape/util';
2
2
  import type { AgentExecution, AgentExecutionChat, AgentExecutionGenerate, AIGenerateTextResolver, AIResolverName, AllOfSchema, AnyServiceConfig, AwsLambdaResolver, BasicAuthentication, BasicResolver, BearerAuthentication, ComposeResolver, CustomAuthentication, DirectiveConfig, DirectiveMappingArray, DirectiveMappingMap, ExtendsSchema, GoogleAuthentication, GraphqlResolver, OAuth2Authentication, OAuth2BearerAuthentication, ObjectSchema, OneOfSchema, ParameterOp, ParameterOpMapping, ParameterOpNested, ParameterOpOp, ParameterOpValue, ParameterSerializeContentOptions, ParameterSerializeOptions, ParameterSerializeStyleOptions, ParameterSerializeStyleOptionsForPathParams, ParameterSerializeStyleOptionsForSearchParams, ProjectSchemaJSON, PropertySchema, RefSchema, RefSchemaLegacy, Resolver, RestResolver, ReturnShape, ReturnShapeArraySchema, SearchParamsAuthentication, ServiceAuthentication, ServiceResolver, ShapedbResolver, ShapeJSON, ShapeMap, ShapeSchemaEnum, TakeshapeResolver, UtilResolver } from '../project-schema/index.ts';
3
- import type { CachedShape, EncryptedServiceConfig, GraphQLServiceConfig, LatestProjectSchemaWithServices, MeshShape, OpenAPIServiceConfig, PropertySchemaWithRelationship, RESTServiceConfig, ReferenceableShape, SchemaWithArgs, SchemaWithRef, ServiceConfigWithCustomAuthentication, ServiceConfigWithOAuth2Authentication, ShopifyServiceConfig } from './types.ts';
4
- import { ArgsType, RefType } from './types.ts';
3
+ import type { CachedShape, EncryptedServiceConfig, GraphQLServiceConfig, LatestProjectSchemaWithServices, MeshShape, OpenAPIServiceConfig, PropertySchemaWithRelationship, RESTServiceConfig, ReferenceableShape, SchemaWithArgs, ServiceConfigWithCustomAuthentication, ServiceConfigWithOAuth2Authentication, ShopifyServiceConfig } from './types.ts';
4
+ import { ArgsType } from './types.ts';
5
5
  /** Resolver Type Utils **/
6
6
  /**
7
7
  * Only tests that the shape is right, not that the name is correct. That's a job for the validator.
@@ -103,12 +103,6 @@ export declare function isCustomAuthentication(authentication: ServiceAuthentica
103
103
  * @param argsSchema Any schema that may have an `args` property.
104
104
  */
105
105
  export declare const getArgsType: (argsSchema: SchemaWithArgs) => Maybe<ArgsType>;
106
- /**
107
- * A utility to return the type of ref present on a schema.
108
- *
109
- * @param refSchema Any schema that may have a `ref` property.
110
- */
111
- export declare const getRefType: (refSchema: SchemaWithRef) => Maybe<RefType>;
112
106
  export declare function isPropertySchemaWithRelationship(schema: PropertySchema): schema is PropertySchemaWithRelationship;
113
107
  export declare function isModelShape(shape: ShapeJSON): boolean;
114
108
  export declare function isCachedShape(shape: ShapeJSON): shape is CachedShape;
@@ -5,7 +5,7 @@ import isPlainObject from 'lodash/isPlainObject.js';
5
5
  import isString from 'lodash/isString.js';
6
6
  import isUndefined from 'lodash/isUndefined.js';
7
7
  import { latestSchemaJson } from "../schemas/index.js";
8
- import { ArgsType, RefType } from "./types.js";
8
+ import { ArgsType } from "./types.js";
9
9
  /** Resolver Type Utils **/
10
10
  /**
11
11
  * Only tests that the shape is right, not that the name is correct. That's a job for the validator.
@@ -240,19 +240,6 @@ export const getArgsType = (argsSchema) => {
240
240
  return ArgsType.args;
241
241
  }
242
242
  };
243
- /**
244
- * A utility to return the type of ref present on a schema.
245
- *
246
- * @param refSchema Any schema that may have a `ref` property.
247
- */
248
- export const getRefType = (refSchema) => {
249
- if (has(refSchema, '@ref')) {
250
- return RefType['@ref'];
251
- }
252
- if (has(refSchema, '$ref')) {
253
- return RefType.$ref;
254
- }
255
- };
256
243
  export function isPropertySchemaWithRelationship(schema) {
257
244
  return schema['@resolver']?.name === 'shapedb:getRelated';
258
245
  }
package/dist/unions.js CHANGED
@@ -10,11 +10,11 @@ export function enumerateOneOfKeys(projectSchema, oneOf) {
10
10
  for (const child of oneOf) {
11
11
  const refItem = getRef(projectSchema, child);
12
12
  if (refItem) {
13
- const shapeName = refItemToNamespacedShapeName(refItem);
13
+ const shapeName = refItemToNamespacedShapeName(projectSchema, refItem);
14
14
  if (projectSchema.shapes[shapeName]) {
15
15
  const shapeId = projectSchema.shapes[shapeName].id;
16
16
  result.push({
17
- propName: getOutputShapeName(camelCase(refItem.typeName)),
17
+ propName: getOutputShapeName(camelCase(refItem.shapeName)),
18
18
  propSchema: child,
19
19
  shapeName,
20
20
  shapeId
@@ -1,5 +1,16 @@
1
- import jsep from 'jsep';
2
- type AnyExpression = jsep.ArrayExpression | jsep.BinaryExpression | jsep.MemberExpression | jsep.CallExpression | jsep.ConditionalExpression | jsep.Identifier | jsep.Literal | jsep.ThisExpression | jsep.UnaryExpression;
1
+ import jsep, { type Expression } from 'jsep';
2
+ export interface ObjectExpression extends Expression {
3
+ type: 'ObjectExpression';
4
+ properties: PropertyExpression[];
5
+ }
6
+ export interface PropertyExpression extends Expression {
7
+ type: 'Property';
8
+ computed: boolean;
9
+ key: AnyExpression;
10
+ value: AnyExpression;
11
+ shorthand: boolean;
12
+ }
13
+ type AnyExpression = jsep.ArrayExpression | jsep.BinaryExpression | jsep.MemberExpression | jsep.CallExpression | jsep.ConditionalExpression | jsep.Identifier | jsep.Literal | jsep.ThisExpression | jsep.UnaryExpression | ObjectExpression | PropertyExpression;
3
14
  export declare const METHODS_NOT_SUPPORTED = "Methods are not supported in expressions";
4
15
  export declare const THIS_NOT_SUPPORTED = "This is not supported in expressions";
5
16
  export declare function parseExpression(expression: string): AnyExpression;
@@ -1,4 +1,6 @@
1
+ import object from '@jsep-plugin/object';
1
2
  import jsep from 'jsep';
3
+ jsep.plugins.register(object);
2
4
  // Default operator precedence from https://github.com/EricSmekens/jsep/blob/master/src/jsep.js#L55
3
5
  const DEFAULT_PRECEDENCE = {
4
6
  '||': 1,
@@ -106,6 +108,14 @@ const unops = {
106
108
  function evaluateArray(list, context) {
107
109
  return list.map((v) => (v ? evaluate(v, context) : undefined));
108
110
  }
111
+ function evaluateObject(properties, context) {
112
+ const obj = {};
113
+ for (const node of properties) {
114
+ const key = !node.computed && node.key.type === 'Identifier' ? node.key.name : evaluate(node.key, context);
115
+ obj[key] = evaluate(node.value, context);
116
+ }
117
+ return obj;
118
+ }
109
119
  function isObject(x) {
110
120
  return Boolean(x) && typeof x === 'object';
111
121
  }
@@ -132,6 +142,8 @@ function evaluate(_node, context) {
132
142
  switch (node.type) {
133
143
  case 'ArrayExpression':
134
144
  return evaluateArray(node.elements, context);
145
+ case 'ObjectExpression':
146
+ return evaluateObject(node.properties, context);
135
147
  case 'CallExpression': {
136
148
  if (node.callee.type === 'MemberExpression') {
137
149
  throw Error(METHODS_NOT_SUPPORTED);
@@ -187,6 +199,15 @@ function validateAST(options, rootNode) {
187
199
  switch (node.type) {
188
200
  case 'ArrayExpression':
189
201
  return node.elements.flatMap((v) => (v ? validate(v, node, 'elements') : []));
202
+ case 'ObjectExpression':
203
+ return node.properties.flatMap((v) => validate(v, node, 'properties'));
204
+ case 'Property': {
205
+ {
206
+ const keyErrors = !node.computed && node.key.type === 'Identifier' ? undefined : validate(node.key, node, 'key');
207
+ const valueErrors = validate(node.value, node, 'value');
208
+ return keyErrors ? [...keyErrors, ...valueErrors] : valueErrors;
209
+ }
210
+ }
190
211
  case 'CallExpression': {
191
212
  if (node.callee.type === 'MemberExpression') {
192
213
  return [{ message: METHODS_NOT_SUPPORTED }];
@@ -307,6 +328,17 @@ export function expressionToString(_node, parent) {
307
328
  const arr = node.elements.map((element) => expressionToString(element, node)).join(',');
308
329
  return `[${arr}]`;
309
330
  }
331
+ if (node.type === 'Property') {
332
+ const keyStr = expressionToString(node.key, node);
333
+ if (node.shorthand) {
334
+ return keyStr;
335
+ }
336
+ return `${node.computed ? `[${keyStr}]` : keyStr}: ${expressionToString(node.value, node)}`;
337
+ }
338
+ if (node.type === 'ObjectExpression') {
339
+ const props = node.properties.map((element) => expressionToString(element, node)).join(',');
340
+ return `{ ${props} }`;
341
+ }
310
342
  if (node.type === 'Literal') {
311
343
  return node.raw;
312
344
  }
@@ -28,7 +28,7 @@ export function normalizeForms(projectSchema) {
28
28
  if (propSchema) {
29
29
  const ref = getRefOrItemsRef(projectSchema, propSchema);
30
30
  if (ref && propConfig.properties) {
31
- const nestedShapeName = refItemToNamespacedShapeName(ref);
31
+ const nestedShapeName = refItemToNamespacedShapeName(projectSchema, ref);
32
32
  normalizedForms[nestedShapeName] = { default: deepClone(propConfig) };
33
33
  storeSourceForm(shapeName, formConfig, propName);
34
34
  normalizeNested(nestedShapeName, propConfig);
@@ -1,5 +1,5 @@
1
1
  import { isDefined, setIsEqual } from '@takeshape/util';
2
- import { dereferenceSchema, getRef, refItemToAtRef } from "../refs.js";
2
+ import { dereferenceSchema, getRef, serializeRef } from "../refs.js";
3
3
  import { isObjectSchema } from "../types/index.js";
4
4
  /**
5
5
  * Normalize ref, oneOf and array schemas and get a list of @ref expressions
@@ -10,7 +10,7 @@ function getRefStrings(context, propertySchema) {
10
10
  return schemas
11
11
  .map((propertySchema) => {
12
12
  const ref = getRef(context, propertySchema);
13
- return ref ? refItemToAtRef(ref) : undefined;
13
+ return ref ? serializeRef(ref) : undefined;
14
14
  })
15
15
  .filter(isDefined);
16
16
  }
@@ -1,4 +1,4 @@
1
- import { refExpressionToRefItem, refItemToShape } from "../refs.js";
1
+ import { parseRef, refItemToShape } from "../refs.js";
2
2
  import { isObjectSchema } from "../types/index.js";
3
3
  import { findSchemaAtPath } from "./find-shape-at-path.js";
4
4
  export function getArgs(prop) {
@@ -8,7 +8,7 @@ export function getArgsSchema(projectSchema, args) {
8
8
  if (typeof args === 'object') {
9
9
  return args;
10
10
  }
11
- const ref = refExpressionToRefItem(projectSchema, args);
11
+ const ref = parseRef(projectSchema, args);
12
12
  const shapeSchema = refItemToShape(projectSchema, ref)?.schema;
13
13
  if (shapeSchema && isObjectSchema(shapeSchema)) {
14
14
  return shapeSchema;
@@ -0,0 +1,3 @@
1
+ import type { PropertySchema } from '../project-schema/index.ts';
2
+ export declare function isAssetProperty(prop: PropertySchema): boolean;
3
+ export declare function isAssetRef(str: string): boolean;
@@ -0,0 +1,11 @@
1
+ import { getRef, parseRef } from "../refs.js";
2
+ export function isAssetProperty(prop) {
3
+ const ref = getRef({}, prop.oneOf?.[0] ?? prop);
4
+ return Boolean(ref && isAssetRefItem(ref));
5
+ }
6
+ export function isAssetRef(str) {
7
+ return isAssetRefItem(parseRef({}, str));
8
+ }
9
+ function isAssetRefItem(ref) {
10
+ return ref.layerId === 'local' && ref.shapeName === 'Asset';
11
+ }
@@ -1,5 +1,5 @@
1
1
  import { assert, deepClone, isDefined, rebaseArray, rebaseObject } from '@takeshape/util';
2
- import { assignWith } from 'lodash';
2
+ import assignWith from 'lodash/assignWith.js';
3
3
  import difference from 'lodash/difference.js';
4
4
  import isEqual from 'lodash/isEqual.js';
5
5
  import last from 'lodash/last.js';
@@ -2,7 +2,7 @@ import { SchemaValidationError } from '@takeshape/errors';
2
2
  import { createAjv } from '@takeshape/json-schema';
3
3
  import { DEFAULT_MIN_SCHEDULE_TRIGGER_INTERVAL, ensureArray, isIntegerLike, isRecord, value } from '@takeshape/util';
4
4
  import { JSONPath } from 'jsonpath-plus';
5
- import { flatten } from 'lodash';
5
+ import flatten from 'lodash/flatten.js';
6
6
  import get from 'lodash/get.js';
7
7
  import initial from 'lodash/initial.js';
8
8
  import isEqual from 'lodash/isEqual.js';
@@ -19,7 +19,7 @@ import neq from 'semver/functions/neq.js';
19
19
  import { builtInShapes } from "../builtin-schema.js";
20
20
  import { isEnumLikeSchema } from "../enum.js";
21
21
  import { isLatestProjectSchemaJSON } from "../project-schema/index.js";
22
- import { atRefToRefItem, createGetNamespace, getRefShapeName, getToolRef, parsePropertyRef, propertyRefItemToPath, propertyRefItemToResolverPath, refItemToAtRef, refItemToNamespacedShapeName, refItemToShape } from "../refs.js";
22
+ import { createGetNamespace, getRefShapeName, getToolRef, isValidServiceId, parsePropertyRef, parseRef, propertyRefItemToPath, propertyRefItemToResolverPath, refItemToNamespacedShapeName, refItemToShape, serializeRef } from "../refs.js";
23
23
  import { getRelationship } from "../relationships.js";
24
24
  import { scalars } from "../scalars.js";
25
25
  import { getAllRefs, isBuiltinMutation, isBuiltinQuery } from "../schema-util.js";
@@ -168,7 +168,7 @@ const validateAIToolConfig = (projectSchema, getNamespace, tool, basePath) => {
168
168
  message: `Unable to parse property ref "${toolRef}"`
169
169
  };
170
170
  }
171
- if (parsed.serviceId !== 'local') {
171
+ if (parsed.layerId !== 'local') {
172
172
  return;
173
173
  }
174
174
  if ((parsed.shapeName === 'Query' && isBuiltinQuery(parsed.propertyName)) ||
@@ -216,7 +216,7 @@ function validateResolver(projectSchema, basePath, baseResolver) {
216
216
  message: `Unable to parse property ref "${resolver.to}"`
217
217
  };
218
218
  }
219
- if (parsed.serviceId !== 'local') {
219
+ if (parsed.layerId !== 'local') {
220
220
  return;
221
221
  }
222
222
  const targetResolver = get(projectSchema, propertyRefItemToResolverPath(getNamespace, parsed));
@@ -363,10 +363,10 @@ async function validateResolverReferences(context, projectSchema, basePath, base
363
363
  const isInvalidPropertyRef = async (refStr) => {
364
364
  const ref = parsePropertyRef(refStr);
365
365
  // ref string format and local refs are validated in validateResolver()
366
- if (!ref || ref.serviceId === 'local') {
366
+ if (!ref || ref.layerId === 'local') {
367
367
  return false;
368
368
  }
369
- const layerState = await context.resolveLayer(ref.serviceId);
369
+ const layerState = await context.resolveLayer(ref.layerId);
370
370
  return layerState.status === 'ok'
371
371
  ? !get(layerState.schema, propertyRefItemToPath(value(''), ref))
372
372
  : !allowDisconnected(context, layerState.status);
@@ -453,8 +453,8 @@ function listShapeJoins(projectSchema) {
453
453
  return joins;
454
454
  }
455
455
  function validateLocalShapeJoinRef(projectSchema, item) {
456
- const refItem = atRefToRefItem(projectSchema, item.ref);
457
- if (refItem.serviceKey === 'local') {
456
+ const refItem = parseRef(projectSchema, item.ref);
457
+ if (refItem.layerId === 'local') {
458
458
  const shape = refItemToShape(projectSchema, refItem);
459
459
  if (!shape) {
460
460
  return [
@@ -472,9 +472,9 @@ function validateLocalShapeJoins(projectSchema) {
472
472
  return listShapeJoins(projectSchema).flatMap((item) => validateLocalShapeJoinRef(projectSchema, item).concat(validateResolver(projectSchema, item.path.concat('resolver'), item.join.resolver)));
473
473
  }
474
474
  async function validateShapeJoinRef(context, projectSchema, item) {
475
- const refItem = atRefToRefItem(projectSchema, item.ref);
475
+ const refItem = parseRef(projectSchema, item.ref);
476
476
  if (refItem) {
477
- const layer = await context.resolveLayer(refItem.serviceKey);
477
+ const layer = await context.resolveLayer(refItem.layerId);
478
478
  const valid = isValidRef(context, projectSchema, layer, refItem);
479
479
  if (!valid) {
480
480
  return [
@@ -587,10 +587,13 @@ function isAllOfPath(path) {
587
587
  const index = path.indexOf('allOf');
588
588
  return index !== -1 && isIntegerLike(path[index + 1]);
589
589
  }
590
+ function isLocalRef(refItem) {
591
+ return refItem.layerId === 'local';
592
+ }
590
593
  function validateLocalRefs(projectSchema) {
591
594
  const errors = [];
592
595
  const shapeNames = new Set([...builtInShapeNames, ...Object.keys(projectSchema.shapes)]);
593
- const refs = getAllRefs(projectSchema).filter((item) => !item.isForeign);
596
+ const refs = getAllRefs(projectSchema).filter(isLocalRef);
594
597
  for (const item of refs) {
595
598
  if (item.template && !isValidTemplate(item.template)) {
596
599
  errors.push({
@@ -599,7 +602,7 @@ function validateLocalRefs(projectSchema) {
599
602
  message: `Invalid template "${item.template}"`
600
603
  });
601
604
  }
602
- const shapeName = refItemToNamespacedShapeName(item);
605
+ const shapeName = refItemToNamespacedShapeName(projectSchema, item);
603
606
  if (!shapeNames.has(shapeName)) {
604
607
  const invalidRef = get(projectSchema, item.path);
605
608
  const path = invalidRef.items ? [...item.path, 'items', '@ref'] : item.path;
@@ -632,10 +635,10 @@ function validateLocalRefs(projectSchema) {
632
635
  return errors;
633
636
  }
634
637
  function isValidRef(context, projectSchema, layer, item) {
635
- const { serviceKey: layerId } = item;
636
- const shapeName = refItemToNamespacedShapeName(item);
638
+ const { layerId } = item;
639
+ const shapeName = refItemToNamespacedShapeName(projectSchema, item);
637
640
  const localShapeExists = Boolean(projectSchema.shapes[shapeName]) || builtInShapeNames.has(shapeName);
638
- return (item.isValidService &&
641
+ return (isValidServiceId(projectSchema, layerId) &&
639
642
  (layerId === 'local' ? localShapeExists : localShapeExists || isValidShapeReference(context, layer, shapeName)));
640
643
  }
641
644
  function mustBeInterface({ path }) {
@@ -647,8 +650,8 @@ async function validateRefs(context, projectSchema) {
647
650
  const refs = getAllRefs(projectSchema);
648
651
  const layerIds = new Set();
649
652
  for (const item of refs) {
650
- if (item.serviceKey !== 'local') {
651
- layerIds.add(item.serviceKey);
653
+ if (item.layerId !== 'local') {
654
+ layerIds.add(item.layerId);
652
655
  }
653
656
  }
654
657
  const layersById = Object.fromEntries(await pMap(layerIds, async (layerId) => [layerId, await resolveLayer(layerId)]));
@@ -660,7 +663,7 @@ async function validateRefs(context, projectSchema) {
660
663
  message: `Invalid template "${item.path}"`
661
664
  });
662
665
  }
663
- const { serviceKey: layerId } = item;
666
+ const { layerId } = item;
664
667
  const layer = layersById[layerId];
665
668
  const valid = isValidRef(context, projectSchema, layer, item);
666
669
  if (!valid) {
@@ -674,7 +677,8 @@ async function validateRefs(context, projectSchema) {
674
677
  // only validate interfaces with connected layers isValidRef above handles when allowDisconnectedLayers false
675
678
  const context = layer?.schema ?? projectSchema;
676
679
  const shape = get(context, item.path.slice(0, 2));
677
- errors.push(...validateShapeImplementsInterface(context, shape, item, item.path));
680
+ const layerWithServices = { ...context, services: projectSchema.services };
681
+ errors.push(...validateShapeImplementsInterface(layerWithServices, shape, item, item.path));
678
682
  }
679
683
  }
680
684
  return errors;
@@ -781,7 +785,7 @@ function validateShapeImplementsInterface(projectSchema, shape, interfaceRefItem
781
785
  errors.push({
782
786
  type: 'notFound',
783
787
  path,
784
- message: `Invalid interface "${refItemToAtRef(interfaceRefItem)}" not found`
788
+ message: `Invalid interface "${serializeRef(interfaceRefItem)}" not found`
785
789
  });
786
790
  }
787
791
  else if (interfaceShape.type !== 'interface') {
@@ -912,6 +916,21 @@ function validateAgents(projectSchema) {
912
916
  })));
913
917
  }
914
918
  }
919
+ if (agent.historyStrategies) {
920
+ const seenStrategyNames = new Set();
921
+ for (const [historyStrategyId, historyStrategy] of Object.entries(agent.historyStrategies)) {
922
+ if (seenStrategyNames.has(historyStrategy.name)) {
923
+ errors.push({
924
+ path: [...agentPath, 'historyStrategies', historyStrategyId, 'name'],
925
+ type: 'conflict',
926
+ message: `Duplicate history strategy name "${historyStrategy.name}"`
927
+ });
928
+ }
929
+ else {
930
+ seenStrategyNames.add(historyStrategy.name);
931
+ }
932
+ }
933
+ }
915
934
  }
916
935
  return errors;
917
936
  }
@@ -323,7 +323,8 @@
323
323
  },
324
324
  "transition": []
325
325
  }
326
- }
326
+ },
327
+ "historyStrategies": {}
327
328
  },
328
329
  "chat": {
329
330
  "api": {
@@ -360,7 +361,8 @@
360
361
  }
361
362
  ]
362
363
  }
363
- }
364
+ },
365
+ "historyStrategies": {}
364
366
  }
365
367
  }
366
368
  }
@@ -305,7 +305,8 @@
305
305
  },
306
306
  "transition": []
307
307
  }
308
- }
308
+ },
309
+ "historyStrategies": {}
309
310
  },
310
311
  "chat": {
311
312
  "api": {
@@ -342,7 +343,8 @@
342
343
  }
343
344
  ]
344
345
  }
345
- }
346
+ },
347
+ "historyStrategies": {}
346
348
  }
347
349
  }
348
350
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takeshape/schema",
3
- "version": "11.89.0",
3
+ "version": "11.92.0",
4
4
  "description": "TakeShape Schema",
5
5
  "homepage": "https://www.takeshape.io",
6
6
  "repository": {
@@ -46,6 +46,7 @@
46
46
  "examples"
47
47
  ],
48
48
  "dependencies": {
49
+ "@jsep-plugin/object": "^1.2.2",
49
50
  "ajv": "8.13.0",
50
51
  "ajv-formats": "3.0.1",
51
52
  "blueimp-md5": "^2.10.0",
@@ -57,9 +58,9 @@
57
58
  "p-reduce": "^2.1.0",
58
59
  "semver": "^7.3.2",
59
60
  "tiny-invariant": "^1.2.0",
60
- "@takeshape/errors": "11.89.0",
61
- "@takeshape/json-schema": "11.89.0",
62
- "@takeshape/util": "11.89.0"
61
+ "@takeshape/errors": "11.92.0",
62
+ "@takeshape/util": "11.92.0",
63
+ "@takeshape/json-schema": "11.92.0"
63
64
  },
64
65
  "devDependencies": {
65
66
  "@takeshape/json-schema-to-typescript": "^11.0.0",
@@ -76,7 +77,7 @@
76
77
  "json-schema-to-ts": "^3.1.1",
77
78
  "meow": "^9.0.0",
78
79
  "shortid": "^2.2.15",
79
- "@takeshape/infra": "11.89.0"
80
+ "@takeshape/infra": "11.92.0"
80
81
  },
81
82
  "engines": {
82
83
  "node": ">=20"