@commercelayer/app-elements 5.2.1 → 5.3.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.
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { u as Ee, j as se, I as $e } from "./main-Bc7WPO8T.js";
2
+ import { u as Ee, j as se, I as $e } from "./main-Du-FJA5W.js";
3
3
  import V, { memo as ce, useState as U, useEffect as I, useRef as w, useCallback as ue, forwardRef as Ce } from "react";
4
4
  function Ie(e, t, r) {
5
5
  return t in e ? Object.defineProperty(e, t, {
@@ -2,7 +2,7 @@
2
2
  var Gr = Object.defineProperty;
3
3
  var Xr = (o, a, t) => a in o ? Gr(o, a, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[a] = t;
4
4
  var y = (o, a, t) => Xr(o, typeof a != "symbol" ? a + "" : a, t);
5
- import { c as z, t as k, m as ht, a as mt, b as me, d as he, n as vt, e as Be, g as wr, f as Zr, h as Jr, s as ot, i as br, k as en, l as _r, o as kr, p as tn, q as rn, r as Ut, v as nn, w as an, x as Kt, y as on, z as Fe, A as sn, j as ne, B as Te, C as _e, D as xt, E as Yt, F as Mr, G as Rt, H as Cr, J as ln, K as Ee, L as Vt, M as cn, N as un, O as dn, P as pn, Q as st, R as fn, I as hn, S as mn, T as vn, U as Dn, V as gn } from "./main-Bc7WPO8T.js";
5
+ import { c as z, t as k, m as ht, a as mt, b as me, d as he, n as vt, e as Be, g as wr, f as Zr, h as Jr, s as ot, i as br, k as en, l as _r, o as kr, p as tn, q as rn, r as Ut, v as nn, w as an, x as Kt, y as on, z as Fe, A as sn, j as ne, B as Te, C as _e, D as xt, E as Yt, F as Mr, G as Rt, H as Cr, J as ln, K as Ee, L as Vt, M as cn, N as un, O as dn, P as pn, Q as st, R as fn, I as hn, S as mn, T as vn, U as Dn, V as gn } from "./main-Du-FJA5W.js";
6
6
  import * as M from "react";
7
7
  import f, { useLayoutEffect as Sr, useEffect as Lt, cloneElement as xr, createRef as Ce, Component as G, useRef as Et, useCallback as yn, createElement as wn, forwardRef as bn, useMemo as _n } from "react";
8
8
  import * as kn from "react-dom";
@@ -1,4 +1,4 @@
1
- import { TokenProviderAllowedApp } from '../providers/TokenProvider/types';
1
+ import { TokenProviderClAppSlug } from '../providers/TokenProvider/types';
2
2
  export interface BackToItem {
3
3
  /**
4
4
  * URL to be stored in sessionStorage, it will be the current URL so it can be used to navigate back.
@@ -34,7 +34,7 @@ interface NavigateToInternalParams {
34
34
  /**
35
35
  * app name to navigate to, it could be the current app (internal linking) or another app (cross linking)
36
36
  */
37
- app: TokenProviderAllowedApp;
37
+ app: TokenProviderClAppSlug;
38
38
  /**
39
39
  * resource id to open
40
40
  */
@@ -49,7 +49,7 @@ interface NavigateToExternalParams {
49
49
  /**
50
50
  * app name to navigate to, it could be the current app (internal linking) or another app (cross linking)
51
51
  */
52
- app: TokenProviderAllowedApp;
52
+ app: TokenProviderClAppSlug;
53
53
  /**
54
54
  * resource id to open
55
55
  */
@@ -1,12 +1,11 @@
1
- import { TokenProviderAllowedApp } from '../providers/TokenProvider/types';
2
- type AppsWithConfig = Exclude<TokenProviderAllowedApp, 'dashboard' | 'resources'>;
1
+ import { TokenProviderClAppSlug } from '../providers/TokenProvider/types';
3
2
  interface UseAppLinkingHook {
4
3
  /**
5
4
  * Navigate to internal app path, to different app (outside router base), or to an external URL.
6
5
  * Current path is saved in session storage to allow going back to it (when using `goBack`).
7
6
  */
8
7
  navigateTo: (param: {
9
- app: AppsWithConfig;
8
+ app: TokenProviderClAppSlug;
10
9
  resourceId?: string;
11
10
  }) => {
12
11
  href: string;
@@ -20771,7 +20771,7 @@ async function Iz({
20771
20771
  mode: (o == null ? void 0 : o.token.test) === !0 ? "test" : "live",
20772
20772
  organizationSlug: i.orgSlug,
20773
20773
  permissions: (o == null ? void 0 : o.permissions) != null ? Lz(o.permissions) : void 0,
20774
- accessibleApps: (o == null ? void 0 : o.accessible_apps) != null ? o == null ? void 0 : o.accessible_apps.map((p) => p.kind) : void 0,
20774
+ accessibleApps: (o == null ? void 0 : o.accessible_apps) != null ? o == null ? void 0 : o.accessible_apps.map((p) => p.kind).filter((p) => p !== "generic") : void 0,
20775
20775
  user: (o == null ? void 0 : o.owner) != null && o.owner.type === "User" ? {
20776
20776
  id: o.owner.id,
20777
20777
  email: o.owner.email,
@@ -29899,7 +29899,7 @@ function pK(t) {
29899
29899
  );
29900
29900
  }
29901
29901
  const fK = e2(
29902
- async () => await import("./CodeEditorComponent-sOC76yJV.js").then((t) => ({
29902
+ async () => await import("./CodeEditorComponent-CTNaTIZn.js").then((t) => ({
29903
29903
  default: t.CodeEditor
29904
29904
  }))
29905
29905
  ), a7 = O(
@@ -30790,7 +30790,7 @@ function o7({
30790
30790
  }
30791
30791
  o7.displayName = "InputCurrencyRange";
30792
30792
  const IK = e2(
30793
- async () => await import("./InputDateComponent-BUnPCCDe.js").then((t) => ({
30793
+ async () => await import("./InputDateComponent-O0J0Np2a.js").then((t) => ({
30794
30794
  default: t.InputDateComponent
30795
30795
  }))
30796
30796
  ), Nr = O(
package/dist/main.d.ts CHANGED
@@ -20,7 +20,7 @@ export { createApp, type ClAppKey, type ClAppProps } from './providers/createApp
20
20
  export { ErrorBoundary } from './providers/ErrorBoundary';
21
21
  export { GTMProvider, useTagManager } from './providers/GTMProvider';
22
22
  export { i18nLocales, I18NProvider, t, Trans, useTranslation, type I18NLocale } from './providers/I18NProvider';
23
- export { encodeExtras, MetaTags, TokenProvider, useTokenProvider, type TokenProviderAllowedApp, type TokenProviderExtras, type TokenProviderPermissionItem, type TokenProviderRoleActions, type TokenProviderRolePermissions, type TokenProviderTokenApplicationKind } from './providers/TokenProvider';
23
+ export { encodeExtras, MetaTags, TokenProvider, useTokenProvider, type TokenProviderAllowedApp, type TokenProviderAllowedAppKind, type TokenProviderAllowedAppSlug, type TokenProviderClAppSlug, type TokenProviderExtras, type TokenProviderPermissionItem, type TokenProviderRoleActions, type TokenProviderRolePermissions, type TokenProviderTokenApplicationKind } from './providers/TokenProvider';
24
24
  export { A, type AProps } from './ui/atoms/A';
25
25
  export { Alert, type AlertProps } from './ui/atoms/Alert';
26
26
  export { Avatar, type AvatarProps } from './ui/atoms/Avatar';
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { aL as s, bp as t, bq as o, aM as r, aN as c, aO as n, aP as u, aQ as i, aR as d, aS as l, aT as p, br as b, aU as g, bO as m, aV as S, aW as I, aw as k, bs as T, bt as R, bu as D, bv as y, aX as h, aA as C, aB as A, bH as P, aY as H, aZ as F, bw as v, bP as f, bQ as B, bR as L, bT as O, bV as E, bY as N, b$ as G, c1 as w, c6 as M, c8 as V, cd as x, ci as W, ck as J, cm as U, co as Y, cq as X, cu as Z, cv as _, cw as $, a_ as j, aE as q, a$ as z, bS as K, bU as Q, bW as aa, bZ as ea, b_ as sa, c0 as ta, c2 as oa, c3 as ra, c4 as ca, c5 as na, c7 as ua, c9 as ia, ce as da, cj as la, cl as pa, cn as ba, cp as ga, cr as ma, cs as Sa, ct as Ia, bx as ka, by as Ta, bz as Ra, bA as Da, bI as ya, aJ as ha, bB as Ca, b0 as Aa, bC as Pa, bD as Ha, b1 as Fa, b2 as va, b3 as fa, b4 as Ba, bE as La, cA as Oa, cB as Ea, cD as Na, cE as Ga, cF as wa, cG as Ma, cH as Va, cI as xa, cK as Wa, cL as Ja, cM as Ua, bJ as Ya, b5 as Xa, bK as Za, b6 as _a, b7 as $a, b8 as ja, b9 as qa, bb as za, bc as Ka, bd as Qa, be as ae, bf as ee, bk as se, bg as te, bL as oe, bl as re, bm as ce, bh as ne, bn as ue, bi as ie, bM as de, aK as le, bN as pe, bo as be, bj as ge, aG as me, ab as Se, az as Ie, bF as ke, bG as Te, _ as Re, $ as De, aa as ye, aI as he, cb as Ce, bX as Ae, a0 as Pe, a1 as He, a2 as Fe, ac as ve, ad as fe, af as Be, cP as Le, cQ as Oe, cc as Ee, a3 as Ne, a4 as Ge, a5 as we, cR as Me, cS as Ve, cT as xe, cU as We, cV as Je, ag as Ue, ah as Ye, cJ as Xe, cW as Ze, cz as _e, ae as $e, cX as je, cY as qe, cZ as ze, ai as Ke, aj as Qe, c_ as as, c$ as es, d0 as ss, am as ts, an as os, W as rs, ak as cs, al as ns, aD as us, Y as is, R as ds, cf as ls, cg as ps, ch as bs, a6 as gs, X as ms, Z as Ss, a7 as Is, cx as ks, a8 as Ts, aF as Rs, a9 as Ds, ao as ys, ap as hs, ax as Cs, ay as As, aq as Ps, ar as Hs, as as Fs, ca as vs, at as fs, au as Bs, av as Ls, cC as Os, cN as Es, cO as Ns, aC as Gs, u as ws, aH as Ms, cy as Vs, ba as xs } from "./main-Bc7WPO8T.js";
2
+ import { aL as s, bp as t, bq as o, aM as r, aN as c, aO as n, aP as u, aQ as i, aR as d, aS as l, aT as p, br as b, aU as g, bO as m, aV as S, aW as I, aw as k, bs as T, bt as R, bu as D, bv as y, aX as h, aA as C, aB as A, bH as P, aY as H, aZ as F, bw as v, bP as f, bQ as B, bR as L, bT as O, bV as E, bY as N, b$ as G, c1 as w, c6 as M, c8 as V, cd as x, ci as W, ck as J, cm as U, co as Y, cq as X, cu as Z, cv as _, cw as $, a_ as j, aE as q, a$ as z, bS as K, bU as Q, bW as aa, bZ as ea, b_ as sa, c0 as ta, c2 as oa, c3 as ra, c4 as ca, c5 as na, c7 as ua, c9 as ia, ce as da, cj as la, cl as pa, cn as ba, cp as ga, cr as ma, cs as Sa, ct as Ia, bx as ka, by as Ta, bz as Ra, bA as Da, bI as ya, aJ as ha, bB as Ca, b0 as Aa, bC as Pa, bD as Ha, b1 as Fa, b2 as va, b3 as fa, b4 as Ba, bE as La, cA as Oa, cB as Ea, cD as Na, cE as Ga, cF as wa, cG as Ma, cH as Va, cI as xa, cK as Wa, cL as Ja, cM as Ua, bJ as Ya, b5 as Xa, bK as Za, b6 as _a, b7 as $a, b8 as ja, b9 as qa, bb as za, bc as Ka, bd as Qa, be as ae, bf as ee, bk as se, bg as te, bL as oe, bl as re, bm as ce, bh as ne, bn as ue, bi as ie, bM as de, aK as le, bN as pe, bo as be, bj as ge, aG as me, ab as Se, az as Ie, bF as ke, bG as Te, _ as Re, $ as De, aa as ye, aI as he, cb as Ce, bX as Ae, a0 as Pe, a1 as He, a2 as Fe, ac as ve, ad as fe, af as Be, cP as Le, cQ as Oe, cc as Ee, a3 as Ne, a4 as Ge, a5 as we, cR as Me, cS as Ve, cT as xe, cU as We, cV as Je, ag as Ue, ah as Ye, cJ as Xe, cW as Ze, cz as _e, ae as $e, cX as je, cY as qe, cZ as ze, ai as Ke, aj as Qe, c_ as as, c$ as es, d0 as ss, am as ts, an as os, W as rs, ak as cs, al as ns, aD as us, Y as is, R as ds, cf as ls, cg as ps, ch as bs, a6 as gs, X as ms, Z as Ss, a7 as Is, cx as ks, a8 as Ts, aF as Rs, a9 as Ds, ao as ys, ap as hs, ax as Cs, ay as As, aq as Ps, ar as Hs, as as Fs, ca as vs, at as fs, au as Bs, av as Ls, cC as Os, cN as Es, cO as Ns, aC as Gs, u as ws, aH as Ms, cy as Vs, ba as xs } from "./main-Du-FJA5W.js";
3
3
  export {
4
4
  s as A,
5
5
  t as ActionButtons,
@@ -1,12 +1,12 @@
1
1
  import { TokenProviderTokenApplicationKind } from '.';
2
2
  import { ListableResourceType } from '@commercelayer/sdk';
3
3
  import { ReactNode } from 'react';
4
- import { TokenProviderAllowedApp, TokenProviderAuthSettings, TokenProviderAuthUser, TokenProviderExtras, TokenProviderRoleActions } from './types';
4
+ import { TokenProviderAllowedAppSlug, TokenProviderAuthSettings, TokenProviderAuthUser, TokenProviderClAppSlug, TokenProviderExtras, TokenProviderRoleActions } from './types';
5
5
  export interface TokenProviderValue {
6
6
  settings: TokenProviderAuthSettings;
7
7
  user: TokenProviderAuthUser | null;
8
8
  canUser: (action: TokenProviderRoleActions, resource: ListableResourceType) => boolean;
9
- canAccess: (appSlug: Exclude<TokenProviderAllowedApp, 'dashboard'>) => boolean;
9
+ canAccess: (appSlug: TokenProviderClAppSlug) => boolean;
10
10
  emitInvalidAuth: (reason: string) => void;
11
11
  }
12
12
  export interface TokenProviderProps {
@@ -16,10 +16,10 @@ export interface TokenProviderProps {
16
16
  */
17
17
  kind: TokenProviderTokenApplicationKind;
18
18
  /**
19
- * The slug of the current app. It needs to match one of the allowed app slugs enabled in the dashboard.
20
- * It is used to persist token for current app only.
19
+ * The slug of the current app. It could match one of the allowed apps or a custom string.
20
+ * It is used as the app identifier (e.g. storage key).
21
21
  */
22
- appSlug: TokenProviderAllowedApp;
22
+ appSlug: TokenProviderAllowedAppSlug;
23
23
  /**
24
24
  * Set this to `true` to skip domain slug validation in dev mode.
25
25
  */
@@ -1,4 +1,4 @@
1
1
  export { encodeExtras } from './extras';
2
2
  export { MetaTags } from './MetaTags';
3
3
  export { TokenProvider, useTokenProvider } from './TokenProvider';
4
- export type { TokenProviderAllowedApp, TokenProviderExtras, TokenProviderPermissionItem, TokenProviderRoleActions, TokenProviderRolePermissions, TokenProviderTokenApplicationKind } from './types';
4
+ export type { TokenProviderAllowedApp, TokenProviderAllowedAppKind, TokenProviderAllowedAppSlug, TokenProviderClAppSlug, TokenProviderExtras, TokenProviderPermissionItem, TokenProviderRoleActions, TokenProviderRolePermissions, TokenProviderTokenApplicationKind } from './types';
@@ -1,11 +1,11 @@
1
- import { TokenProviderAllowedApp } from '.';
1
+ import { TokenProviderClAppSlug } from '.';
2
2
  import { TokenProviderAuthSettings, TokenProviderAuthUser, TokenProviderRolePermissions } from './types';
3
3
  interface TokenProviderInternalState {
4
4
  validAuthToken?: string;
5
5
  isLoading: boolean;
6
6
  isTokenError: boolean;
7
7
  rolePermissions: TokenProviderRolePermissions;
8
- accessibleApps: TokenProviderAllowedApp[];
8
+ accessibleApps: TokenProviderClAppSlug[];
9
9
  settings: TokenProviderAuthSettings;
10
10
  user: TokenProviderAuthUser | null;
11
11
  }
@@ -18,7 +18,7 @@ type Action = {
18
18
  settings: TokenProviderAuthSettings;
19
19
  user: TokenProviderAuthUser | null;
20
20
  rolePermissions: TokenProviderRolePermissions;
21
- accessibleApps: TokenProviderAllowedApp[];
21
+ accessibleApps: TokenProviderClAppSlug[];
22
22
  };
23
23
  };
24
24
  export declare const reducer: (state: TokenProviderInternalState, action: Action) => TokenProviderInternalState;
@@ -1,13 +1,13 @@
1
- import { TokenProviderAllowedApp } from './types';
1
+ import { TokenProviderAllowedAppSlug } from './types';
2
2
  type ItemType = 'accessToken' | 'extras';
3
3
  export declare function makeStorageKey({ appSlug, organizationSlug, itemType }: {
4
- appSlug: TokenProviderAllowedApp;
4
+ appSlug: TokenProviderAllowedAppSlug;
5
5
  organizationSlug: string;
6
6
  itemType: ItemType;
7
7
  }): string;
8
8
  export declare function getPersistentJWT({ appSlug, organizationSlug, itemType }: {
9
9
  /** The app for which to get the token. */
10
- appSlug: TokenProviderAllowedApp;
10
+ appSlug: TokenProviderAllowedAppSlug;
11
11
  /** The organization slug for the token we want to retrieve. */
12
12
  organizationSlug?: string;
13
13
  /** The JWT item type you want to retrieve. */
@@ -15,7 +15,7 @@ export declare function getPersistentJWT({ appSlug, organizationSlug, itemType }
15
15
  }): string | null;
16
16
  export declare function savePersistentJWT({ appSlug, jwt, organizationSlug, itemType }: {
17
17
  /** The app for which to get the token. */
18
- appSlug: TokenProviderAllowedApp;
18
+ appSlug: TokenProviderAllowedAppSlug;
19
19
  /** The token to save. */
20
20
  jwt: string;
21
21
  /** The organization slug for the token we want to store. */
@@ -1,7 +1,28 @@
1
1
  import { ParsedScopes } from './getInfoFromJwt';
2
2
  import { ListableResourceType } from '@commercelayer/sdk';
3
- export type TokenProviderAllowedApp = 'bundles' | 'customers' | 'exports' | 'gift_cards' | 'imports' | 'inventory' | 'orders' | 'price_lists' | 'promotions' | 'returns' | 'shipments' | 'sku_lists' | 'skus' | 'stock_transfers' | 'subscriptions' | 'tags' | 'webhooks' | 'dashboard' | 'resources' | 'generic';
4
- export type TokenProviderTokenApplicationKind = 'integration' | 'sales_channel' | 'webapp' | 'resources' | TokenProviderAllowedApp;
3
+ export type TokenProviderClAppSlug = 'bundles' | 'customers' | 'exports' | 'gift_cards' | 'imports' | 'inventory' | 'orders' | 'price_lists' | 'promotions' | 'returns' | 'shipments' | 'sku_lists' | 'skus' | 'stock_transfers' | 'subscriptions' | 'tags' | 'webhooks';
4
+ /**
5
+ * TokenProviderAllowedApp is a type that contains all the possible kinds of the app that you can create inside the dashboard.
6
+ * As a convention Commerce Layer official apps have a slug that matches the kind of the app.
7
+ */
8
+ export type TokenProviderAllowedAppKind = TokenProviderClAppSlug | 'generic';
9
+ /**
10
+ * @deprecated Use `TokenProviderAllowedAppKind` instead.
11
+ */
12
+ export type TokenProviderAllowedApp = TokenProviderAllowedAppKind;
13
+ /**
14
+ * The application slug. It could match one of the allowed apps or a custom string.
15
+ * It is used as the app identifier (e.g. storage key).
16
+ */
17
+ export type TokenProviderAllowedAppSlug = TokenProviderClAppSlug | (string & {});
18
+ /**
19
+ * TokenProviderTokenApplicationKind is a type that contains all the suitable api credential kinds.
20
+ * Depending on the kind, it could be used to identify:
21
+ * - an authentication api credential (eg. `integration`, `sales_channel`, `webapp`)
22
+ * - a particular feature in the dashboard (eg. `resources`, `links`)
23
+ * - an app with its dedicated set of permissions (eg. `order`, `customers`, etc...)
24
+ */
25
+ export type TokenProviderTokenApplicationKind = 'integration' | 'sales_channel' | 'webapp' | 'resources' | 'links' | TokenProviderAllowedAppKind;
5
26
  export type TokenProviderRoleActions = 'create' | 'destroy' | 'read' | 'update';
6
27
  export type TokenProviderPermissionItem = Record<TokenProviderRoleActions, boolean>;
7
28
  export type TokenProviderRolePermissions = Partial<Record<ListableResourceType | 'organizations', TokenProviderPermissionItem>>;
@@ -70,7 +91,7 @@ export interface TokenProviderTokenInfo {
70
91
  */
71
92
  accessible_apps?: Array<{
72
93
  name: string;
73
- kind: TokenProviderAllowedApp;
94
+ kind: TokenProviderAllowedAppKind;
74
95
  core: boolean;
75
96
  }>;
76
97
  }
@@ -1,6 +1,6 @@
1
- import { TokenProviderAllowedApp, TokenProviderTokenApplicationKind } from '.';
1
+ import { TokenProviderTokenApplicationKind } from '.';
2
2
  import { ParsedScopes } from './getInfoFromJwt';
3
- import { Mode, TokenProviderAuthUser, TokenProviderRolePermissions } from './types';
3
+ import { Mode, TokenProviderAuthUser, TokenProviderClAppSlug, TokenProviderRolePermissions } from './types';
4
4
  export declare function isTokenExpired({ accessToken, compareTo }: {
5
5
  accessToken: string;
6
6
  compareTo: Date;
@@ -11,7 +11,7 @@ interface ValidToken {
11
11
  mode: Mode;
12
12
  organizationSlug: string;
13
13
  permissions?: TokenProviderRolePermissions;
14
- accessibleApps?: TokenProviderAllowedApp[];
14
+ accessibleApps?: TokenProviderClAppSlug[];
15
15
  user: TokenProviderAuthUser | null;
16
16
  scopes?: ParsedScopes;
17
17
  }
@@ -1,8 +1,8 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { Root } from 'react-dom/client';
3
- import { TokenProviderAllowedApp } from './TokenProvider';
4
3
  import { TokenProviderProps } from './TokenProvider/TokenProvider';
5
- export type ClAppKey = `clApp_${TokenProviderAllowedApp}`;
4
+ import { TokenProviderAllowedAppSlug } from './TokenProvider/types';
5
+ export type ClAppKey = `clApp_${TokenProviderAllowedAppSlug}`;
6
6
  /**
7
7
  * Method to mount the React application in the provider `node` with the set of options passed as `props`.
8
8
  */
@@ -31,5 +31,5 @@ export interface ClAppProps extends Partial<Omit<TokenProviderProps, 'appSlug' |
31
31
  * The React application will them be mounted into the provided `node` element, when the `init` method is called.
32
32
  * @param children - The root component of the app.
33
33
  **/
34
- export declare function createApp(children: (props: ClAppProps) => ReactNode, appSlug: TokenProviderAllowedApp): void;
34
+ export declare function createApp(children: (props: ClAppProps) => ReactNode, appSlug: TokenProviderAllowedAppSlug): void;
35
35
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commercelayer/app-elements",
3
- "version": "5.2.1",
3
+ "version": "5.3.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "files": [