@thisisagile/easy 15.12.12 → 15.12.13

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.
@@ -48,7 +48,7 @@ export declare class EasyUri<Props = UriExpandProps> implements Uri {
48
48
  static readonly skip: Segment;
49
49
  static readonly take: Segment;
50
50
  readonly host: Segment;
51
- readonly resource: Segment;
51
+ protected resource: Segment;
52
52
  protected state: any;
53
53
  constructor(segments?: Segment[]);
54
54
  get path(): string;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/Uri.ts"],"sourcesContent":["import { isBoolean, isDefined, isNotEmpty, isTrue } from './Is';\nimport { asString, Text } from './Text';\nimport { toName } from './Constructor';\nimport { ctx } from './Context';\nimport { List, toList } from './List';\nimport { entries, meta } from \"./Meta\";\nimport { tryTo } from './Try';\nimport { Optional } from './Types';\nimport { OneOrMore, toArray } from './Array';\n\nexport type Segment = Text & { key?: string; segment?: string; query?: (value: unknown) => string };\n\nexport const toSegment = (\n key?: Text,\n {\n segment,\n query,\n }: {\n segment?: string;\n query?: (value: unknown) => string;\n } = {}\n): Segment => ({\n key: key as string,\n segment,\n query,\n toString: () => asString(key),\n});\n\nexport const uri = {\n host: (key?: string): Segment => toSegment(key, { segment: key ?? ctx.env.host ?? '$host' }),\n resource: (resource: Uri): Segment => toSegment(toName(resource, 'Uri'), { segment: toName(resource, 'Uri') }),\n segment: (key?: Text): Segment => toSegment(key, { segment: key as string }),\n path: (key: Text): Segment => toSegment(key, { segment: `:${key}` }),\n query: (key: Text): Segment => toSegment(key, { query: (value: unknown): string => (isDefined(value) ? `${key}=${value}` : '') }),\n boolean: (key: Text): Segment => toSegment(key, { query: (value: unknown): string => (isTrue(value) ? `${key}` : '') }),\n};\n\ntype Prop = { segment: Segment; value: any };\n\nconst toRoute = (...segments: Segment[]): string =>\n toList(segments)\n .mapDefined(s => s.segment)\n .join('/');\n\nexport type Uri = {\n id: (id?: unknown) => Uri;\n ids: (ids: OneOrMore<unknown>) => Uri;\n query: (q?: unknown) => Uri;\n sort: (q?: any) => Uri;\n skip: (n?: number) => Uri;\n take: (n?: number) => Uri;\n path: string;\n route: (resource: string) => string;\n isInternal: boolean;\n toString: () => string;\n};\n\nexport type UriExpandProps = { q: string, s: string };\n\nexport class EasyUri<Props = UriExpandProps> implements Uri {\n static readonly id = uri.path('id');\n static readonly ids = uri.query('ids');\n static readonly query = uri.query('q');\n static readonly sort = uri.query('s');\n static readonly skip = uri.query('skip');\n static readonly take = uri.query('take');\n\n readonly host = uri.host();\n readonly resource = uri.resource(this);\n\n protected state: any = {};\n\n constructor(readonly segments: Segment[] = []) {}\n\n get path(): string {\n return toRoute(uri.segment(''), this.resource, ...this.segments);\n }\n\n get complete(): string {\n return toRoute(this.host, this.resource, ...this.segments);\n }\n\n get isInternal(): boolean {\n return toRoute(this.host) === (ctx.env.host ?? '$host');\n }\n\n protected get props(): List<Prop> {\n return meta(this.state).values<Prop>();\n }\n\n route = (resource: Optional<string> = this.resource.key): string => toRoute(uri.segment(''), uri.segment(resource?.toLowerCase()), ...this.segments);\n\n set = (segment: Segment, value?: unknown): this => {\n tryTo(value)\n .is.defined()\n .accept(value => (this.state[segment.key ?? ''] = { segment, value }));\n return this;\n };\n\n toString(): string {\n return tryTo(() => this.props)\n .map(ps => ps.filter(p => p.segment?.segment))\n .map(ps => ps.reduce((r: string, p: Prop) => r.replace(asString(p.segment.segment), asString(p.value)), this.complete))\n .map(route => ({\n route,\n query: this.props.mapDefined(p => (p.segment?.query ? p.segment?.query(p.value) : undefined))?.join('&'),\n }))\n .map(({ route, query }) => (isNotEmpty(query) ? `${route}?${query}` : route)).value;\n }\n\n id = (id?: unknown): this => this.set(EasyUri.id, id);\n ids = (ids: OneOrMore<unknown>): this => this.set(EasyUri.ids, toArray(ids).join(','));\n query = (q?: unknown): this => this.set(EasyUri.query, q);\n sort = (s?: any): this => this.set(EasyUri.sort, asString(s));\n\n skip = (index?: number): this => this.set(EasyUri.skip, index);\n take = (items?: number): this => this.set(EasyUri.take, items);\n\n expand(props: Partial<Props>): this {\n return entries(props)\n .filter(([_, v]) => isNotEmpty(v))\n .reduce((u, [k, v]) => (isBoolean(v) ? u.set(uri.boolean(k), v) : u.set(uri.query(k), toArray(v).join(','))), this);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAyD;AACzD,kBAA+B;AAC/B,yBAAuB;AACvB,qBAAoB;AACpB,kBAA6B;AAC7B,kBAA8B;AAC9B,iBAAsB;AAEtB,mBAAmC;AAI5B,MAAM,YAAY,CACvB,KACA;AAAA,EACE;AAAA,EACA;AACF,IAGI,CAAC,OACQ;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU,UAAM,sBAAS,GAAG;AAC9B;AAEO,MAAM,MAAM;AAAA,EACjB,MAAM,CAAC,QAA0B,UAAU,KAAK,EAAE,SAAS,OAAO,mBAAI,IAAI,QAAQ,QAAQ,CAAC;AAAA,EAC3F,UAAU,CAAC,aAA2B,cAAU,2BAAO,UAAU,KAAK,GAAG,EAAE,aAAS,2BAAO,UAAU,KAAK,EAAE,CAAC;AAAA,EAC7G,SAAS,CAAC,QAAwB,UAAU,KAAK,EAAE,SAAS,IAAc,CAAC;AAAA,EAC3E,MAAM,CAAC,QAAuB,UAAU,KAAK,EAAE,SAAS,IAAI,GAAG,GAAG,CAAC;AAAA,EACnE,OAAO,CAAC,QAAuB,UAAU,KAAK,EAAE,OAAO,CAAC,cAA4B,qBAAU,KAAK,IAAI,GAAG,GAAG,IAAI,KAAK,KAAK,GAAI,CAAC;AAAA,EAChI,SAAS,CAAC,QAAuB,UAAU,KAAK,EAAE,OAAO,CAAC,cAA4B,kBAAO,KAAK,IAAI,GAAG,GAAG,KAAK,GAAI,CAAC;AACxH;AAIA,MAAM,UAAU,IAAI,iBAClB,oBAAO,QAAQ,EACZ,WAAW,OAAK,EAAE,OAAO,EACzB,KAAK,GAAG;AAiBN,MAAM,QAA+C;AAAA,EAa1D,YAAqB,WAAsB,CAAC,GAAG;AAA1B;AAAA,EAA2B;AAAA,EAZhD,OAAgB,KAAK,IAAI,KAAK,IAAI;AAAA,EAClC,OAAgB,MAAM,IAAI,MAAM,KAAK;AAAA,EACrC,OAAgB,QAAQ,IAAI,MAAM,GAAG;AAAA,EACrC,OAAgB,OAAO,IAAI,MAAM,GAAG;AAAA,EACpC,OAAgB,OAAO,IAAI,MAAM,MAAM;AAAA,EACvC,OAAgB,OAAO,IAAI,MAAM,MAAM;AAAA,EAE9B,OAAO,IAAI,KAAK;AAAA,EAChB,WAAW,IAAI,SAAS,IAAI;AAAA,EAE3B,QAAa,CAAC;AAAA,EAIxB,IAAI,OAAe;AACjB,WAAO,QAAQ,IAAI,QAAQ,EAAE,GAAG,KAAK,UAAU,GAAG,KAAK,QAAQ;AAAA,EACjE;AAAA,EAEA,IAAI,WAAmB;AACrB,WAAO,QAAQ,KAAK,MAAM,KAAK,UAAU,GAAG,KAAK,QAAQ;AAAA,EAC3D;AAAA,EAEA,IAAI,aAAsB;AACxB,WAAO,QAAQ,KAAK,IAAI,OAAO,mBAAI,IAAI,QAAQ;AAAA,EACjD;AAAA,EAEA,IAAc,QAAoB;AAChC,eAAO,kBAAK,KAAK,KAAK,EAAE,OAAa;AAAA,EACvC;AAAA,EAEA,QAAQ,CAAC,WAA6B,KAAK,SAAS,QAAgB,QAAQ,IAAI,QAAQ,EAAE,GAAG,IAAI,QAAQ,UAAU,YAAY,CAAC,GAAG,GAAG,KAAK,QAAQ;AAAA,EAEnJ,MAAM,CAAC,SAAkB,UAA0B;AACjD,0BAAM,KAAK,EACR,GAAG,QAAQ,EACX,OAAO,CAAAA,WAAU,KAAK,MAAM,QAAQ,OAAO,EAAE,IAAI,EAAE,SAAS,OAAAA,OAAM,CAAE;AACvE,WAAO;AAAA,EACT;AAAA,EAEA,WAAmB;AACjB,eAAO,kBAAM,MAAM,KAAK,KAAK,EAC1B,IAAI,QAAM,GAAG,OAAO,OAAK,EAAE,SAAS,OAAO,CAAC,EAC5C,IAAI,QAAM,GAAG,OAAO,CAAC,GAAW,MAAY,EAAE,YAAQ,sBAAS,EAAE,QAAQ,OAAO,OAAG,sBAAS,EAAE,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,EACrH,IAAI,YAAU;AAAA,MACb;AAAA,MACA,OAAO,KAAK,MAAM,WAAW,OAAM,EAAE,SAAS,QAAQ,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,MAAU,GAAG,KAAK,GAAG;AAAA,IACzG,EAAE,EACD,IAAI,CAAC,EAAE,OAAO,MAAM,UAAO,sBAAW,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,KAAM,EAAE;AAAA,EAClF;AAAA,EAEA,KAAK,CAAC,OAAuB,KAAK,IAAI,QAAQ,IAAI,EAAE;AAAA,EACpD,MAAM,CAAC,QAAkC,KAAK,IAAI,QAAQ,SAAK,sBAAQ,GAAG,EAAE,KAAK,GAAG,CAAC;AAAA,EACrF,QAAQ,CAAC,MAAsB,KAAK,IAAI,QAAQ,OAAO,CAAC;AAAA,EACxD,OAAO,CAAC,MAAkB,KAAK,IAAI,QAAQ,UAAM,sBAAS,CAAC,CAAC;AAAA,EAE5D,OAAO,CAAC,UAAyB,KAAK,IAAI,QAAQ,MAAM,KAAK;AAAA,EAC7D,OAAO,CAAC,UAAyB,KAAK,IAAI,QAAQ,MAAM,KAAK;AAAA,EAE7D,OAAO,OAA6B;AAClC,eAAO,qBAAQ,KAAK,EACjB,OAAO,CAAC,CAAC,GAAG,CAAC,UAAM,sBAAW,CAAC,CAAC,EAChC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAO,qBAAU,CAAC,IAAI,EAAE,IAAI,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,MAAM,CAAC,OAAG,sBAAQ,CAAC,EAAE,KAAK,GAAG,CAAC,GAAI,IAAI;AAAA,EACtH;AACF;","names":["value"]}
1
+ {"version":3,"sources":["../../src/types/Uri.ts"],"sourcesContent":["import { isBoolean, isDefined, isNotEmpty, isTrue } from './Is';\nimport { asString, Text } from './Text';\nimport { toName } from './Constructor';\nimport { ctx } from './Context';\nimport { List, toList } from './List';\nimport { entries, meta } from './Meta';\nimport { tryTo } from './Try';\nimport { Optional } from './Types';\nimport { OneOrMore, toArray } from './Array';\n\nexport type Segment = Text & { key?: string; segment?: string; query?: (value: unknown) => string };\n\nexport const toSegment = (\n key?: Text,\n {\n segment,\n query,\n }: {\n segment?: string;\n query?: (value: unknown) => string;\n } = {}\n): Segment => ({\n key: key as string,\n segment,\n query,\n toString: () => asString(key),\n});\n\nexport const uri = {\n host: (key?: string): Segment => toSegment(key, { segment: key ?? ctx.env.host ?? '$host' }),\n resource: (resource: Uri): Segment => toSegment(toName(resource, 'Uri'), { segment: toName(resource, 'Uri') }),\n segment: (key?: Text): Segment => toSegment(key, { segment: key as string }),\n path: (key: Text): Segment => toSegment(key, { segment: `:${key}` }),\n query: (key: Text): Segment => toSegment(key, { query: (value: unknown): string => (isDefined(value) ? `${key}=${value}` : '') }),\n boolean: (key: Text): Segment => toSegment(key, { query: (value: unknown): string => (isTrue(value) ? `${key}` : '') }),\n};\n\ntype Prop = { segment: Segment; value: any };\n\nconst toRoute = (...segments: Segment[]): string =>\n toList(segments)\n .mapDefined(s => s.segment)\n .join('/');\n\nexport type Uri = {\n id: (id?: unknown) => Uri;\n ids: (ids: OneOrMore<unknown>) => Uri;\n query: (q?: unknown) => Uri;\n sort: (q?: any) => Uri;\n skip: (n?: number) => Uri;\n take: (n?: number) => Uri;\n path: string;\n route: (resource: string) => string;\n isInternal: boolean;\n toString: () => string;\n};\n\nexport type UriExpandProps = { q: string; s: string };\n\nexport class EasyUri<Props = UriExpandProps> implements Uri {\n static readonly id = uri.path('id');\n static readonly ids = uri.query('ids');\n static readonly query = uri.query('q');\n static readonly sort = uri.query('s');\n static readonly skip = uri.query('skip');\n static readonly take = uri.query('take');\n\n readonly host = uri.host();\n protected resource = uri.resource(this);\n\n protected state: any = {};\n\n constructor(readonly segments: Segment[] = []) {}\n\n get path(): string {\n return toRoute(uri.segment(''), this.resource, ...this.segments);\n }\n\n get complete(): string {\n return toRoute(this.host, this.resource, ...this.segments);\n }\n\n get isInternal(): boolean {\n return toRoute(this.host) === (ctx.env.host ?? '$host');\n }\n\n protected get props(): List<Prop> {\n return meta(this.state).values<Prop>();\n }\n\n route = (resource: Optional<string> = this.resource.key): string => toRoute(uri.segment(''), uri.segment(resource?.toLowerCase()), ...this.segments);\n\n set = (segment: Segment, value?: unknown): this => {\n tryTo(value)\n .is.defined()\n .accept(value => (this.state[segment.key ?? ''] = { segment, value }));\n return this;\n };\n\n toString(): string {\n return tryTo(() => this.props)\n .map(ps => ps.filter(p => p.segment?.segment))\n .map(ps => ps.reduce((r: string, p: Prop) => r.replace(asString(p.segment.segment), asString(p.value)), this.complete))\n .map(route => ({\n route,\n query: this.props.mapDefined(p => (p.segment?.query ? p.segment?.query(p.value) : undefined))?.join('&'),\n }))\n .map(({ route, query }) => (isNotEmpty(query) ? `${route}?${query}` : route)).value;\n }\n\n id = (id?: unknown): this => this.set(EasyUri.id, id);\n ids = (ids: OneOrMore<unknown>): this => this.set(EasyUri.ids, toArray(ids).join(','));\n query = (q?: unknown): this => this.set(EasyUri.query, q);\n sort = (s?: any): this => this.set(EasyUri.sort, asString(s));\n\n skip = (index?: number): this => this.set(EasyUri.skip, index);\n take = (items?: number): this => this.set(EasyUri.take, items);\n\n expand(props: Partial<Props>): this {\n return entries(props)\n .filter(([_, v]) => isNotEmpty(v))\n .reduce((u, [k, v]) => (isBoolean(v) ? u.set(uri.boolean(k), v) : u.set(uri.query(k), toArray(v).join(','))), this);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAyD;AACzD,kBAA+B;AAC/B,yBAAuB;AACvB,qBAAoB;AACpB,kBAA6B;AAC7B,kBAA8B;AAC9B,iBAAsB;AAEtB,mBAAmC;AAI5B,MAAM,YAAY,CACvB,KACA;AAAA,EACE;AAAA,EACA;AACF,IAGI,CAAC,OACQ;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU,UAAM,sBAAS,GAAG;AAC9B;AAEO,MAAM,MAAM;AAAA,EACjB,MAAM,CAAC,QAA0B,UAAU,KAAK,EAAE,SAAS,OAAO,mBAAI,IAAI,QAAQ,QAAQ,CAAC;AAAA,EAC3F,UAAU,CAAC,aAA2B,cAAU,2BAAO,UAAU,KAAK,GAAG,EAAE,aAAS,2BAAO,UAAU,KAAK,EAAE,CAAC;AAAA,EAC7G,SAAS,CAAC,QAAwB,UAAU,KAAK,EAAE,SAAS,IAAc,CAAC;AAAA,EAC3E,MAAM,CAAC,QAAuB,UAAU,KAAK,EAAE,SAAS,IAAI,GAAG,GAAG,CAAC;AAAA,EACnE,OAAO,CAAC,QAAuB,UAAU,KAAK,EAAE,OAAO,CAAC,cAA4B,qBAAU,KAAK,IAAI,GAAG,GAAG,IAAI,KAAK,KAAK,GAAI,CAAC;AAAA,EAChI,SAAS,CAAC,QAAuB,UAAU,KAAK,EAAE,OAAO,CAAC,cAA4B,kBAAO,KAAK,IAAI,GAAG,GAAG,KAAK,GAAI,CAAC;AACxH;AAIA,MAAM,UAAU,IAAI,iBAClB,oBAAO,QAAQ,EACZ,WAAW,OAAK,EAAE,OAAO,EACzB,KAAK,GAAG;AAiBN,MAAM,QAA+C;AAAA,EAa1D,YAAqB,WAAsB,CAAC,GAAG;AAA1B;AAAA,EAA2B;AAAA,EAZhD,OAAgB,KAAK,IAAI,KAAK,IAAI;AAAA,EAClC,OAAgB,MAAM,IAAI,MAAM,KAAK;AAAA,EACrC,OAAgB,QAAQ,IAAI,MAAM,GAAG;AAAA,EACrC,OAAgB,OAAO,IAAI,MAAM,GAAG;AAAA,EACpC,OAAgB,OAAO,IAAI,MAAM,MAAM;AAAA,EACvC,OAAgB,OAAO,IAAI,MAAM,MAAM;AAAA,EAE9B,OAAO,IAAI,KAAK;AAAA,EACf,WAAW,IAAI,SAAS,IAAI;AAAA,EAE5B,QAAa,CAAC;AAAA,EAIxB,IAAI,OAAe;AACjB,WAAO,QAAQ,IAAI,QAAQ,EAAE,GAAG,KAAK,UAAU,GAAG,KAAK,QAAQ;AAAA,EACjE;AAAA,EAEA,IAAI,WAAmB;AACrB,WAAO,QAAQ,KAAK,MAAM,KAAK,UAAU,GAAG,KAAK,QAAQ;AAAA,EAC3D;AAAA,EAEA,IAAI,aAAsB;AACxB,WAAO,QAAQ,KAAK,IAAI,OAAO,mBAAI,IAAI,QAAQ;AAAA,EACjD;AAAA,EAEA,IAAc,QAAoB;AAChC,eAAO,kBAAK,KAAK,KAAK,EAAE,OAAa;AAAA,EACvC;AAAA,EAEA,QAAQ,CAAC,WAA6B,KAAK,SAAS,QAAgB,QAAQ,IAAI,QAAQ,EAAE,GAAG,IAAI,QAAQ,UAAU,YAAY,CAAC,GAAG,GAAG,KAAK,QAAQ;AAAA,EAEnJ,MAAM,CAAC,SAAkB,UAA0B;AACjD,0BAAM,KAAK,EACR,GAAG,QAAQ,EACX,OAAO,CAAAA,WAAU,KAAK,MAAM,QAAQ,OAAO,EAAE,IAAI,EAAE,SAAS,OAAAA,OAAM,CAAE;AACvE,WAAO;AAAA,EACT;AAAA,EAEA,WAAmB;AACjB,eAAO,kBAAM,MAAM,KAAK,KAAK,EAC1B,IAAI,QAAM,GAAG,OAAO,OAAK,EAAE,SAAS,OAAO,CAAC,EAC5C,IAAI,QAAM,GAAG,OAAO,CAAC,GAAW,MAAY,EAAE,YAAQ,sBAAS,EAAE,QAAQ,OAAO,OAAG,sBAAS,EAAE,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,EACrH,IAAI,YAAU;AAAA,MACb;AAAA,MACA,OAAO,KAAK,MAAM,WAAW,OAAM,EAAE,SAAS,QAAQ,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,MAAU,GAAG,KAAK,GAAG;AAAA,IACzG,EAAE,EACD,IAAI,CAAC,EAAE,OAAO,MAAM,UAAO,sBAAW,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,KAAM,EAAE;AAAA,EAClF;AAAA,EAEA,KAAK,CAAC,OAAuB,KAAK,IAAI,QAAQ,IAAI,EAAE;AAAA,EACpD,MAAM,CAAC,QAAkC,KAAK,IAAI,QAAQ,SAAK,sBAAQ,GAAG,EAAE,KAAK,GAAG,CAAC;AAAA,EACrF,QAAQ,CAAC,MAAsB,KAAK,IAAI,QAAQ,OAAO,CAAC;AAAA,EACxD,OAAO,CAAC,MAAkB,KAAK,IAAI,QAAQ,UAAM,sBAAS,CAAC,CAAC;AAAA,EAE5D,OAAO,CAAC,UAAyB,KAAK,IAAI,QAAQ,MAAM,KAAK;AAAA,EAC7D,OAAO,CAAC,UAAyB,KAAK,IAAI,QAAQ,MAAM,KAAK;AAAA,EAE7D,OAAO,OAA6B;AAClC,eAAO,qBAAQ,KAAK,EACjB,OAAO,CAAC,CAAC,GAAG,CAAC,UAAM,sBAAW,CAAC,CAAC,EAChC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAO,qBAAU,CAAC,IAAI,EAAE,IAAI,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,MAAM,CAAC,OAAG,sBAAQ,CAAC,EAAE,KAAK,GAAG,CAAC,GAAI,IAAI;AAAA,EACtH;AACF;","names":["value"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/Uri.ts"],"sourcesContent":["import { isBoolean, isDefined, isNotEmpty, isTrue } from './Is';\nimport { asString, Text } from './Text';\nimport { toName } from './Constructor';\nimport { ctx } from './Context';\nimport { List, toList } from './List';\nimport { entries, meta } from \"./Meta\";\nimport { tryTo } from './Try';\nimport { Optional } from './Types';\nimport { OneOrMore, toArray } from './Array';\n\nexport type Segment = Text & { key?: string; segment?: string; query?: (value: unknown) => string };\n\nexport const toSegment = (\n key?: Text,\n {\n segment,\n query,\n }: {\n segment?: string;\n query?: (value: unknown) => string;\n } = {}\n): Segment => ({\n key: key as string,\n segment,\n query,\n toString: () => asString(key),\n});\n\nexport const uri = {\n host: (key?: string): Segment => toSegment(key, { segment: key ?? ctx.env.host ?? '$host' }),\n resource: (resource: Uri): Segment => toSegment(toName(resource, 'Uri'), { segment: toName(resource, 'Uri') }),\n segment: (key?: Text): Segment => toSegment(key, { segment: key as string }),\n path: (key: Text): Segment => toSegment(key, { segment: `:${key}` }),\n query: (key: Text): Segment => toSegment(key, { query: (value: unknown): string => (isDefined(value) ? `${key}=${value}` : '') }),\n boolean: (key: Text): Segment => toSegment(key, { query: (value: unknown): string => (isTrue(value) ? `${key}` : '') }),\n};\n\ntype Prop = { segment: Segment; value: any };\n\nconst toRoute = (...segments: Segment[]): string =>\n toList(segments)\n .mapDefined(s => s.segment)\n .join('/');\n\nexport type Uri = {\n id: (id?: unknown) => Uri;\n ids: (ids: OneOrMore<unknown>) => Uri;\n query: (q?: unknown) => Uri;\n sort: (q?: any) => Uri;\n skip: (n?: number) => Uri;\n take: (n?: number) => Uri;\n path: string;\n route: (resource: string) => string;\n isInternal: boolean;\n toString: () => string;\n};\n\nexport type UriExpandProps = { q: string, s: string };\n\nexport class EasyUri<Props = UriExpandProps> implements Uri {\n static readonly id = uri.path('id');\n static readonly ids = uri.query('ids');\n static readonly query = uri.query('q');\n static readonly sort = uri.query('s');\n static readonly skip = uri.query('skip');\n static readonly take = uri.query('take');\n\n readonly host = uri.host();\n readonly resource = uri.resource(this);\n\n protected state: any = {};\n\n constructor(readonly segments: Segment[] = []) {}\n\n get path(): string {\n return toRoute(uri.segment(''), this.resource, ...this.segments);\n }\n\n get complete(): string {\n return toRoute(this.host, this.resource, ...this.segments);\n }\n\n get isInternal(): boolean {\n return toRoute(this.host) === (ctx.env.host ?? '$host');\n }\n\n protected get props(): List<Prop> {\n return meta(this.state).values<Prop>();\n }\n\n route = (resource: Optional<string> = this.resource.key): string => toRoute(uri.segment(''), uri.segment(resource?.toLowerCase()), ...this.segments);\n\n set = (segment: Segment, value?: unknown): this => {\n tryTo(value)\n .is.defined()\n .accept(value => (this.state[segment.key ?? ''] = { segment, value }));\n return this;\n };\n\n toString(): string {\n return tryTo(() => this.props)\n .map(ps => ps.filter(p => p.segment?.segment))\n .map(ps => ps.reduce((r: string, p: Prop) => r.replace(asString(p.segment.segment), asString(p.value)), this.complete))\n .map(route => ({\n route,\n query: this.props.mapDefined(p => (p.segment?.query ? p.segment?.query(p.value) : undefined))?.join('&'),\n }))\n .map(({ route, query }) => (isNotEmpty(query) ? `${route}?${query}` : route)).value;\n }\n\n id = (id?: unknown): this => this.set(EasyUri.id, id);\n ids = (ids: OneOrMore<unknown>): this => this.set(EasyUri.ids, toArray(ids).join(','));\n query = (q?: unknown): this => this.set(EasyUri.query, q);\n sort = (s?: any): this => this.set(EasyUri.sort, asString(s));\n\n skip = (index?: number): this => this.set(EasyUri.skip, index);\n take = (items?: number): this => this.set(EasyUri.take, items);\n\n expand(props: Partial<Props>): this {\n return entries(props)\n .filter(([_, v]) => isNotEmpty(v))\n .reduce((u, [k, v]) => (isBoolean(v) ? u.set(uri.boolean(k), v) : u.set(uri.query(k), toArray(v).join(','))), this);\n }\n}\n"],"mappings":"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","names":["value"]}
1
+ {"version":3,"sources":["../../src/types/Uri.ts"],"sourcesContent":["import { isBoolean, isDefined, isNotEmpty, isTrue } from './Is';\nimport { asString, Text } from './Text';\nimport { toName } from './Constructor';\nimport { ctx } from './Context';\nimport { List, toList } from './List';\nimport { entries, meta } from './Meta';\nimport { tryTo } from './Try';\nimport { Optional } from './Types';\nimport { OneOrMore, toArray } from './Array';\n\nexport type Segment = Text & { key?: string; segment?: string; query?: (value: unknown) => string };\n\nexport const toSegment = (\n key?: Text,\n {\n segment,\n query,\n }: {\n segment?: string;\n query?: (value: unknown) => string;\n } = {}\n): Segment => ({\n key: key as string,\n segment,\n query,\n toString: () => asString(key),\n});\n\nexport const uri = {\n host: (key?: string): Segment => toSegment(key, { segment: key ?? ctx.env.host ?? '$host' }),\n resource: (resource: Uri): Segment => toSegment(toName(resource, 'Uri'), { segment: toName(resource, 'Uri') }),\n segment: (key?: Text): Segment => toSegment(key, { segment: key as string }),\n path: (key: Text): Segment => toSegment(key, { segment: `:${key}` }),\n query: (key: Text): Segment => toSegment(key, { query: (value: unknown): string => (isDefined(value) ? `${key}=${value}` : '') }),\n boolean: (key: Text): Segment => toSegment(key, { query: (value: unknown): string => (isTrue(value) ? `${key}` : '') }),\n};\n\ntype Prop = { segment: Segment; value: any };\n\nconst toRoute = (...segments: Segment[]): string =>\n toList(segments)\n .mapDefined(s => s.segment)\n .join('/');\n\nexport type Uri = {\n id: (id?: unknown) => Uri;\n ids: (ids: OneOrMore<unknown>) => Uri;\n query: (q?: unknown) => Uri;\n sort: (q?: any) => Uri;\n skip: (n?: number) => Uri;\n take: (n?: number) => Uri;\n path: string;\n route: (resource: string) => string;\n isInternal: boolean;\n toString: () => string;\n};\n\nexport type UriExpandProps = { q: string; s: string };\n\nexport class EasyUri<Props = UriExpandProps> implements Uri {\n static readonly id = uri.path('id');\n static readonly ids = uri.query('ids');\n static readonly query = uri.query('q');\n static readonly sort = uri.query('s');\n static readonly skip = uri.query('skip');\n static readonly take = uri.query('take');\n\n readonly host = uri.host();\n protected resource = uri.resource(this);\n\n protected state: any = {};\n\n constructor(readonly segments: Segment[] = []) {}\n\n get path(): string {\n return toRoute(uri.segment(''), this.resource, ...this.segments);\n }\n\n get complete(): string {\n return toRoute(this.host, this.resource, ...this.segments);\n }\n\n get isInternal(): boolean {\n return toRoute(this.host) === (ctx.env.host ?? '$host');\n }\n\n protected get props(): List<Prop> {\n return meta(this.state).values<Prop>();\n }\n\n route = (resource: Optional<string> = this.resource.key): string => toRoute(uri.segment(''), uri.segment(resource?.toLowerCase()), ...this.segments);\n\n set = (segment: Segment, value?: unknown): this => {\n tryTo(value)\n .is.defined()\n .accept(value => (this.state[segment.key ?? ''] = { segment, value }));\n return this;\n };\n\n toString(): string {\n return tryTo(() => this.props)\n .map(ps => ps.filter(p => p.segment?.segment))\n .map(ps => ps.reduce((r: string, p: Prop) => r.replace(asString(p.segment.segment), asString(p.value)), this.complete))\n .map(route => ({\n route,\n query: this.props.mapDefined(p => (p.segment?.query ? p.segment?.query(p.value) : undefined))?.join('&'),\n }))\n .map(({ route, query }) => (isNotEmpty(query) ? `${route}?${query}` : route)).value;\n }\n\n id = (id?: unknown): this => this.set(EasyUri.id, id);\n ids = (ids: OneOrMore<unknown>): this => this.set(EasyUri.ids, toArray(ids).join(','));\n query = (q?: unknown): this => this.set(EasyUri.query, q);\n sort = (s?: any): this => this.set(EasyUri.sort, asString(s));\n\n skip = (index?: number): this => this.set(EasyUri.skip, index);\n take = (items?: number): this => this.set(EasyUri.take, items);\n\n expand(props: Partial<Props>): this {\n return entries(props)\n .filter(([_, v]) => isNotEmpty(v))\n .reduce((u, [k, v]) => (isBoolean(v) ? u.set(uri.boolean(k), v) : u.set(uri.query(k), toArray(v).join(','))), this);\n }\n}\n"],"mappings":"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","names":["value"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thisisagile/easy",
3
- "version": "15.12.12",
3
+ "version": "15.12.13",
4
4
  "description": "Straightforward library for building domain-driven microservice architectures",
5
5
  "author": "Sander Hoogendoorn",
6
6
  "license": "MIT",
@@ -33,7 +33,7 @@
33
33
  "access": "public"
34
34
  },
35
35
  "devDependencies": {
36
- "@thisisagile/easy-test": "15.12.12",
36
+ "@thisisagile/easy-test": "15.12.13",
37
37
  "@types/form-urlencoded": "^4.4.0",
38
38
  "@types/jsonwebtoken": "^9.0.2",
39
39
  "@types/luxon": "3.2.0",
package/src/types/Uri.ts CHANGED
@@ -3,7 +3,7 @@ import { asString, Text } from './Text';
3
3
  import { toName } from './Constructor';
4
4
  import { ctx } from './Context';
5
5
  import { List, toList } from './List';
6
- import { entries, meta } from "./Meta";
6
+ import { entries, meta } from './Meta';
7
7
  import { tryTo } from './Try';
8
8
  import { Optional } from './Types';
9
9
  import { OneOrMore, toArray } from './Array';
@@ -55,7 +55,7 @@ export type Uri = {
55
55
  toString: () => string;
56
56
  };
57
57
 
58
- export type UriExpandProps = { q: string, s: string };
58
+ export type UriExpandProps = { q: string; s: string };
59
59
 
60
60
  export class EasyUri<Props = UriExpandProps> implements Uri {
61
61
  static readonly id = uri.path('id');
@@ -66,7 +66,7 @@ export class EasyUri<Props = UriExpandProps> implements Uri {
66
66
  static readonly take = uri.query('take');
67
67
 
68
68
  readonly host = uri.host();
69
- readonly resource = uri.resource(this);
69
+ protected resource = uri.resource(this);
70
70
 
71
71
  protected state: any = {};
72
72