fix: address comments

This commit is contained in:
Fredrik Adelöw
2020-09-23 20:13:30 +02:00
parent 0222279021
commit 1ef015d68c
5 changed files with 62 additions and 46 deletions
+1 -2
View File
@@ -17,8 +17,7 @@
export { entityMetaGeneratedFields } from './Entity';
export type { Entity, EntityMeta } from './Entity';
export * from './policies';
export { parseEntityName, parseEntityRef, serializeEntityRef } from './ref';
export type { EntityRefContext } from './ref';
export { parseEntityName, serializeEntityRef } from './ref';
export {
entityHasChanges,
generateEntityEtag,
@@ -68,33 +68,40 @@ describe('ref', () => {
expect(() =>
parseEntityName({ kind: '', namespace: 'b', name: 'c' }),
).toThrow();
expect(() => parseEntityName({ namespace: 'b', name: 'c' })).toThrow();
expect(() =>
parseEntityName({ kind: 'a', namespace: '', name: 'c' }),
).toThrow();
expect(() => parseEntityName({ kind: 'a', name: 'c' })).not.toThrow();
expect(() =>
parseEntityName({ kind: 'a', namespace: 'b', name: '' }),
).toThrow();
expect(() =>
parseEntityName({ kind: 'a', namespace: 'b' } as any),
).toThrow();
// two are empty
expect(() =>
parseEntityName({ kind: '', namespace: '', name: 'c' }),
).toThrow();
expect(() => parseEntityName({ name: 'c' })).toThrow();
expect(() =>
parseEntityName({ kind: '', namespace: 'b', name: '' }),
).toThrow();
expect(() => parseEntityName({ namespace: 'b' } as any)).toThrow();
expect(() =>
parseEntityName({ kind: 'a', namespace: '', name: '' }),
).toThrow();
expect(() => parseEntityName({ kind: 'a' } as any)).toThrow();
// three are empty
expect(() =>
parseEntityName({ kind: '', namespace: '', name: '' }),
).toThrow();
expect(() => parseEntityName({} as any)).toThrow();
// one is left out, one empty
expect(() => parseEntityName({ namespace: '', name: 'c' })).toThrow();
expect(() => parseEntityName({ namespace: 'b', name: '' })).toThrow();
expect(() => parseEntityName({ kind: '', name: 'c' })).toThrow();
expect(() => parseEntityName({ kind: 'a', name: '' })).toThrow();
// nothing at all
expect(() => parseEntityName({} as any)).toThrow();
});
it('adds defaults where necessary to strings', () => {
+40 -22
View File
@@ -14,12 +14,12 @@
* limitations under the License.
*/
import { CompoundEntityRef, EntityName, EntityRef } from '../types';
import { EntityName, EntityRef } from '../types';
/**
* The context of defaults that entity reference parsing happens within.
*/
export type EntityRefContext = {
type EntityRefContext = {
/** The default kind, if none is given in the reference */
defaultKind?: string;
/** The default namespace, if none is given in the reference */
@@ -53,19 +53,7 @@ export function parseEntityName(
);
}
// This is a corner case - when the ref contained a namespace but it was the
// empty string (so the default did not kick in)
if (!namespace) {
throw new Error(
`Entity reference ${kind}:${name} did not contain a namespace`,
);
}
return {
kind,
namespace: namespace!,
name,
};
return { kind, namespace, name };
}
/**
@@ -79,16 +67,44 @@ export function parseEntityName(
* @param context The context of defaults that the parsing happens within
* @returns The compound form of the reference
*/
export function parseEntityRef(
ref: EntityRef,
context?: { defaultKind: string },
): {
kind: string;
namespace?: string;
name: string;
};
export function parseEntityRef(
ref: EntityRef,
context?: { defaultNamespace: string },
): {
kind?: string;
namespace: string;
name: string;
};
export function parseEntityRef(
ref: EntityRef,
context?: { defaultKind: string; defaultNamespace: string },
): {
kind: string;
namespace: string;
name: string;
};
export function parseEntityRef(
ref: EntityRef,
context: EntityRefContext = {},
): CompoundEntityRef {
): {
kind?: string;
namespace?: string;
name: string;
} {
if (!ref) {
throw new Error(`Entity reference must not be empty`);
}
if (typeof ref === 'string') {
const match = /^(?:([^:/]+):)?(?:([^:/]+)\/)?([^:/]+)$/.exec(ref.trim());
const match = /^([^:/]+:)?([^:/]+\/)?([^:/]+)$/.exec(ref.trim());
if (!match) {
throw new Error(
`Entity reference "${ref}" was not on the form [<kind>:][<namespace>/]<name>`,
@@ -96,8 +112,8 @@ export function parseEntityRef(
}
return {
kind: match[1] ?? context.defaultKind,
namespace: match[2] ?? context.defaultNamespace,
kind: match[1]?.slice(0, -1) ?? context.defaultKind,
namespace: match[2]?.slice(0, -1) ?? context.defaultNamespace,
name: match[3],
};
}
@@ -127,9 +143,11 @@ export function parseEntityRef(
* @param ref The reference to serialize
* @returns The same reference on either string or compound form
*/
export function serializeEntityRef(
ref: CompoundEntityRef | EntityName,
): EntityRef {
export function serializeEntityRef(ref: {
kind?: string;
namespace?: string;
name: string;
}): EntityRef {
const { kind, namespace, name } = ref;
if (
kind?.includes(':') ||
+1 -7
View File
@@ -18,11 +18,5 @@ export * from './entity';
export { EntityPolicies } from './EntityPolicies';
export * from './kinds';
export * from './location';
export type {
CompoundEntityRef,
EntityName,
EntityPolicy,
EntityRef,
JSONSchema,
} from './types';
export type { EntityName, EntityPolicy, EntityRef, JSONSchema } from './types';
export * from './validation';
+11 -13
View File
@@ -45,20 +45,18 @@ export type EntityName = {
};
/**
* A reference by name to an entity, where the kind and/or the namespace can be
* left out.
* A reference by name to an entity, either as a compact string representation,
* or as a compound reference structure.
*
* The string representation is on the form [<kind>:][<namespace>/]<name>.
*
* Left-out parts of the reference need to be handled by the application,
* either by rejecting the reference or by falling back to default values.
*/
export type CompoundEntityRef = {
kind?: string;
namespace?: string;
name: string;
};
/**
* A reference by name to an entity, either as a compact string representation,
* or as a compound reference structure.
*/
export type EntityRef = string | CompoundEntityRef;
export type EntityRef =
| string
| {
kind?: string;
namespace?: string;
name: string;
};