@uniformdev/next-app-router 20.48.0 → 20.48.1-alpha.11

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.
package/dist/handler.mjs CHANGED
@@ -314,11 +314,25 @@ async function handleRateLimits(callApi) {
314
314
  }
315
315
  const base = Math.pow(2, backoffRetries - backoffRetriesLeft) * 333;
316
316
  const backoffWait = base + Math.round(Math.random() * (base / 2)) * (Math.random() > 0.5 ? 1 : -1);
317
- await new Promise((resolve) => setTimeout(resolve, resetWait + backoffWait));
317
+ await new Promise((resolve) => setTimeout(resolve, Math.max(0, resetWait + backoffWait)));
318
318
  backoffRetriesLeft -= 1;
319
319
  }
320
320
  return response;
321
321
  }
322
+ var isPlainObject = (obj) => typeof obj === "object" && obj !== null && !Array.isArray(obj);
323
+ function rewriteFiltersForApi(filters) {
324
+ return Object.entries(filters != null ? filters : {}).reduce(
325
+ (acc, [key, value]) => {
326
+ const lhs = `filters.${key}` + (isPlainObject(value) ? `[${Object.keys(value)[0]}]` : "");
327
+ const rhs = isPlainObject(value) ? Object.values(value)[0] : value;
328
+ return {
329
+ ...acc,
330
+ [lhs]: Array.isArray(rhs) ? rhs.map((v) => `${v}`.trim()).join(",") : `${rhs}`.trim()
331
+ };
332
+ },
333
+ {}
334
+ );
335
+ }
322
336
  var _url;
323
337
  var _AggregateClient = class _AggregateClient2 extends ApiClient {
324
338
  constructor(options) {
@@ -1101,20 +1115,6 @@ function createLimitPolicy({
1101
1115
  return currentFunc();
1102
1116
  };
1103
1117
  }
1104
- var isPlainObject = (obj) => typeof obj === "object" && obj !== null && !Array.isArray(obj);
1105
- function rewriteFilters(filters) {
1106
- return Object.entries(filters != null ? filters : {}).reduce(
1107
- (acc, [key, value]) => {
1108
- const lhs = `filters.${key}` + (isPlainObject(value) ? `[${Object.keys(value)[0]}]` : "");
1109
- const rhs = isPlainObject(value) ? Object.values(value)[0] : value;
1110
- return {
1111
- ...acc,
1112
- [lhs]: Array.isArray(rhs) ? rhs.map((v) => `${v}`.trim()).join(",") : `${rhs}`.trim()
1113
- };
1114
- },
1115
- {}
1116
- );
1117
- }
1118
1118
  var CANVAS_URL = "/api/v1/canvas";
1119
1119
  var CanvasClient = class extends ApiClient {
1120
1120
  constructor(options) {
@@ -1130,7 +1130,7 @@ var CanvasClient = class extends ApiClient {
1130
1130
  async getCompositionList(params = {}) {
1131
1131
  const { projectId } = this.options;
1132
1132
  const { resolveData, filters, ...originParams } = params;
1133
- const rewrittenFilters = rewriteFilters(filters);
1133
+ const rewrittenFilters = rewriteFiltersForApi(filters);
1134
1134
  if (!resolveData) {
1135
1135
  const fetchUri = this.createUrl(CANVAS_URL, { ...originParams, projectId, ...rewrittenFilters });
1136
1136
  return this.apiClient(fetchUri);
@@ -1250,7 +1250,7 @@ var _ContentClient = class _ContentClient2 extends ApiClient {
1250
1250
  getEntries(options) {
1251
1251
  const { projectId } = this.options;
1252
1252
  const { skipDataResolution, filters, ...params } = options;
1253
- const rewrittenFilters = rewriteFilters(filters);
1253
+ const rewrittenFilters = rewriteFiltersForApi(filters);
1254
1254
  if (skipDataResolution) {
1255
1255
  const url = this.createUrl(__privateGet2(_ContentClient2, _entriesUrl), { ...params, ...rewrittenFilters, projectId });
1256
1256
  return this.apiClient(url);
@@ -1400,13 +1400,19 @@ function parseVariableExpression(serialized, onToken) {
1400
1400
  bufferEndIndex = index + 1;
1401
1401
  continue;
1402
1402
  }
1403
- state = "variable";
1404
- if (bufferEndIndex > bufferStartIndex) {
1403
+ if (state === "variable") {
1404
+ const textStart = bufferStartIndex - variablePrefix.length;
1405
+ if (handleToken(serialized.substring(textStart, bufferEndIndex), "text") === false) {
1406
+ return tokenCount;
1407
+ }
1408
+ bufferStartIndex = bufferEndIndex;
1409
+ } else if (bufferEndIndex > bufferStartIndex) {
1405
1410
  if (handleToken(serialized.substring(bufferStartIndex, bufferEndIndex), "text") === false) {
1406
1411
  return tokenCount;
1407
1412
  }
1408
1413
  bufferStartIndex = bufferEndIndex;
1409
1414
  }
1415
+ state = "variable";
1410
1416
  index += variablePrefix.length - 1;
1411
1417
  bufferStartIndex += variablePrefix.length;
1412
1418
  continue;
@@ -1428,11 +1434,11 @@ function parseVariableExpression(serialized, onToken) {
1428
1434
  }
1429
1435
  bufferEndIndex++;
1430
1436
  }
1431
- if (bufferEndIndex > bufferStartIndex) {
1432
- if (state === "variable") {
1433
- state = "text";
1434
- bufferStartIndex -= variablePrefix.length;
1435
- }
1437
+ if (state === "variable") {
1438
+ state = "text";
1439
+ bufferStartIndex -= variablePrefix.length;
1440
+ }
1441
+ if (bufferStartIndex < serialized.length) {
1436
1442
  handleToken(serialized.substring(bufferStartIndex), state);
1437
1443
  }
1438
1444
  return tokenCount;
@@ -1482,6 +1488,7 @@ var _IntegrationPropertyEditorsClient = class _IntegrationPropertyEditorsClient2
1482
1488
  _baseUrl = /* @__PURE__ */ new WeakMap();
1483
1489
  __privateAdd2(_IntegrationPropertyEditorsClient, _baseUrl, "/api/v1/integration-property-editors");
1484
1490
  var _url22;
1491
+ var _projectsUrl;
1485
1492
  var _ProjectClient = class _ProjectClient2 extends ApiClient {
1486
1493
  constructor(options) {
1487
1494
  super({ ...options, bypassCache: true });
@@ -1491,6 +1498,15 @@ var _ProjectClient = class _ProjectClient2 extends ApiClient {
1491
1498
  const fetchUri = this.createUrl(__privateGet2(_ProjectClient2, _url22), { ...options });
1492
1499
  return await this.apiClient(fetchUri);
1493
1500
  }
1501
+ /**
1502
+ * Fetches projects grouped by team.
1503
+ * When teamId is provided, returns a single team with its projects.
1504
+ * When omitted, returns all accessible teams and their projects.
1505
+ */
1506
+ async getProjects(options) {
1507
+ const fetchUri = this.createUrl(__privateGet2(_ProjectClient2, _projectsUrl), options ? { ...options } : {});
1508
+ return await this.apiClient(fetchUri);
1509
+ }
1494
1510
  /** Updates or creates (based on id) a Project */
1495
1511
  async upsert(body) {
1496
1512
  const fetchUri = this.createUrl(__privateGet2(_ProjectClient2, _url22));
@@ -1510,7 +1526,9 @@ var _ProjectClient = class _ProjectClient2 extends ApiClient {
1510
1526
  }
1511
1527
  };
1512
1528
  _url22 = /* @__PURE__ */ new WeakMap();
1529
+ _projectsUrl = /* @__PURE__ */ new WeakMap();
1513
1530
  __privateAdd2(_ProjectClient, _url22, "/api/v1/project");
1531
+ __privateAdd2(_ProjectClient, _projectsUrl, "/api/v1/projects");
1514
1532
  var isAllowedReferrer = (referrer) => {
1515
1533
  return Boolean(referrer == null ? void 0 : referrer.match(/(^https:\/\/|\.)(uniform.app|uniform.wtf|localhost:\d{4})\//));
1516
1534
  };
@@ -1523,6 +1541,9 @@ import { NextResponse } from "next/server";
1523
1541
  // src/config/helpers.ts
1524
1542
  import config from "@uniformdev/next-app-router/config/resolved";
1525
1543
  var getMiddlewareRuntimeCache = () => {
1544
+ if (process.env.NODE_ENV === "development" && !process.env.RUNTIME_CACHE_ENDPOINT) {
1545
+ return false;
1546
+ }
1526
1547
  if (typeof config.middlewareRuntimeCache === "boolean") {
1527
1548
  return config.middlewareRuntimeCache;
1528
1549
  }
@@ -1750,6 +1771,9 @@ var isDevelopmentEnvironment = () => {
1750
1771
  };
1751
1772
 
1752
1773
  // src/clients/cache.ts
1774
+ var isSpecificCacheMode = (options) => {
1775
+ return "cache" in options;
1776
+ };
1753
1777
  var isStateCacheMode = (options) => {
1754
1778
  return "state" in options;
1755
1779
  };
@@ -1771,7 +1795,9 @@ var resolveCache = ({
1771
1795
  }) => {
1772
1796
  let cache = void 0;
1773
1797
  if (options) {
1774
- if (isStateCacheMode(options)) {
1798
+ if (isSpecificCacheMode(options)) {
1799
+ cache = options.cache;
1800
+ } else if (isStateCacheMode(options)) {
1775
1801
  if (options.state === CANVAS_DRAFT_STATE || options.state === CANVAS_EDITOR_STATE) {
1776
1802
  cache = {
1777
1803
  type: "no-cache",
package/dist/index.esm.js CHANGED
@@ -320,11 +320,25 @@ async function handleRateLimits(callApi) {
320
320
  }
321
321
  const base = Math.pow(2, backoffRetries - backoffRetriesLeft) * 333;
322
322
  const backoffWait = base + Math.round(Math.random() * (base / 2)) * (Math.random() > 0.5 ? 1 : -1);
323
- await new Promise((resolve) => setTimeout(resolve, resetWait + backoffWait));
323
+ await new Promise((resolve) => setTimeout(resolve, Math.max(0, resetWait + backoffWait)));
324
324
  backoffRetriesLeft -= 1;
325
325
  }
326
326
  return response;
327
327
  }
328
+ var isPlainObject = (obj) => typeof obj === "object" && obj !== null && !Array.isArray(obj);
329
+ function rewriteFiltersForApi(filters) {
330
+ return Object.entries(filters != null ? filters : {}).reduce(
331
+ (acc, [key, value]) => {
332
+ const lhs = `filters.${key}` + (isPlainObject(value) ? `[${Object.keys(value)[0]}]` : "");
333
+ const rhs = isPlainObject(value) ? Object.values(value)[0] : value;
334
+ return {
335
+ ...acc,
336
+ [lhs]: Array.isArray(rhs) ? rhs.map((v) => `${v}`.trim()).join(",") : `${rhs}`.trim()
337
+ };
338
+ },
339
+ {}
340
+ );
341
+ }
328
342
  var _url;
329
343
  var _AggregateClient = class _AggregateClient2 extends ApiClient {
330
344
  constructor(options) {
@@ -1108,20 +1122,6 @@ function createLimitPolicy({
1108
1122
  return currentFunc();
1109
1123
  };
1110
1124
  }
1111
- var isPlainObject = (obj) => typeof obj === "object" && obj !== null && !Array.isArray(obj);
1112
- function rewriteFilters(filters) {
1113
- return Object.entries(filters != null ? filters : {}).reduce(
1114
- (acc, [key, value]) => {
1115
- const lhs = `filters.${key}` + (isPlainObject(value) ? `[${Object.keys(value)[0]}]` : "");
1116
- const rhs = isPlainObject(value) ? Object.values(value)[0] : value;
1117
- return {
1118
- ...acc,
1119
- [lhs]: Array.isArray(rhs) ? rhs.map((v) => `${v}`.trim()).join(",") : `${rhs}`.trim()
1120
- };
1121
- },
1122
- {}
1123
- );
1124
- }
1125
1125
  var CANVAS_URL = "/api/v1/canvas";
1126
1126
  var CanvasClient = class extends ApiClient {
1127
1127
  constructor(options) {
@@ -1137,7 +1137,7 @@ var CanvasClient = class extends ApiClient {
1137
1137
  async getCompositionList(params = {}) {
1138
1138
  const { projectId } = this.options;
1139
1139
  const { resolveData, filters, ...originParams } = params;
1140
- const rewrittenFilters = rewriteFilters(filters);
1140
+ const rewrittenFilters = rewriteFiltersForApi(filters);
1141
1141
  if (!resolveData) {
1142
1142
  const fetchUri = this.createUrl(CANVAS_URL, { ...originParams, projectId, ...rewrittenFilters });
1143
1143
  return this.apiClient(fetchUri);
@@ -1257,7 +1257,7 @@ var _ContentClient = class _ContentClient2 extends ApiClient {
1257
1257
  getEntries(options) {
1258
1258
  const { projectId } = this.options;
1259
1259
  const { skipDataResolution, filters, ...params } = options;
1260
- const rewrittenFilters = rewriteFilters(filters);
1260
+ const rewrittenFilters = rewriteFiltersForApi(filters);
1261
1261
  if (skipDataResolution) {
1262
1262
  const url = this.createUrl(__privateGet2(_ContentClient2, _entriesUrl), { ...params, ...rewrittenFilters, projectId });
1263
1263
  return this.apiClient(url);
@@ -1450,13 +1450,19 @@ function parseVariableExpression(serialized, onToken) {
1450
1450
  bufferEndIndex = index + 1;
1451
1451
  continue;
1452
1452
  }
1453
- state = "variable";
1454
- if (bufferEndIndex > bufferStartIndex) {
1453
+ if (state === "variable") {
1454
+ const textStart = bufferStartIndex - variablePrefix.length;
1455
+ if (handleToken(serialized.substring(textStart, bufferEndIndex), "text") === false) {
1456
+ return tokenCount;
1457
+ }
1458
+ bufferStartIndex = bufferEndIndex;
1459
+ } else if (bufferEndIndex > bufferStartIndex) {
1455
1460
  if (handleToken(serialized.substring(bufferStartIndex, bufferEndIndex), "text") === false) {
1456
1461
  return tokenCount;
1457
1462
  }
1458
1463
  bufferStartIndex = bufferEndIndex;
1459
1464
  }
1465
+ state = "variable";
1460
1466
  index += variablePrefix.length - 1;
1461
1467
  bufferStartIndex += variablePrefix.length;
1462
1468
  continue;
@@ -1478,11 +1484,11 @@ function parseVariableExpression(serialized, onToken) {
1478
1484
  }
1479
1485
  bufferEndIndex++;
1480
1486
  }
1481
- if (bufferEndIndex > bufferStartIndex) {
1482
- if (state === "variable") {
1483
- state = "text";
1484
- bufferStartIndex -= variablePrefix.length;
1485
- }
1487
+ if (state === "variable") {
1488
+ state = "text";
1489
+ bufferStartIndex -= variablePrefix.length;
1490
+ }
1491
+ if (bufferStartIndex < serialized.length) {
1486
1492
  handleToken(serialized.substring(bufferStartIndex), state);
1487
1493
  }
1488
1494
  return tokenCount;
@@ -1843,6 +1849,7 @@ var _IntegrationPropertyEditorsClient = class _IntegrationPropertyEditorsClient2
1843
1849
  _baseUrl = /* @__PURE__ */ new WeakMap();
1844
1850
  __privateAdd2(_IntegrationPropertyEditorsClient, _baseUrl, "/api/v1/integration-property-editors");
1845
1851
  var _url22;
1852
+ var _projectsUrl;
1846
1853
  var _ProjectClient = class _ProjectClient2 extends ApiClient {
1847
1854
  constructor(options) {
1848
1855
  super({ ...options, bypassCache: true });
@@ -1852,6 +1859,15 @@ var _ProjectClient = class _ProjectClient2 extends ApiClient {
1852
1859
  const fetchUri = this.createUrl(__privateGet2(_ProjectClient2, _url22), { ...options });
1853
1860
  return await this.apiClient(fetchUri);
1854
1861
  }
1862
+ /**
1863
+ * Fetches projects grouped by team.
1864
+ * When teamId is provided, returns a single team with its projects.
1865
+ * When omitted, returns all accessible teams and their projects.
1866
+ */
1867
+ async getProjects(options) {
1868
+ const fetchUri = this.createUrl(__privateGet2(_ProjectClient2, _projectsUrl), options ? { ...options } : {});
1869
+ return await this.apiClient(fetchUri);
1870
+ }
1855
1871
  /** Updates or creates (based on id) a Project */
1856
1872
  async upsert(body) {
1857
1873
  const fetchUri = this.createUrl(__privateGet2(_ProjectClient2, _url22));
@@ -1871,7 +1887,9 @@ var _ProjectClient = class _ProjectClient2 extends ApiClient {
1871
1887
  }
1872
1888
  };
1873
1889
  _url22 = /* @__PURE__ */ new WeakMap();
1890
+ _projectsUrl = /* @__PURE__ */ new WeakMap();
1874
1891
  __privateAdd2(_ProjectClient, _url22, "/api/v1/project");
1892
+ __privateAdd2(_ProjectClient, _projectsUrl, "/api/v1/projects");
1875
1893
  var ROUTE_URL = "/api/v1/route";
1876
1894
  var RouteClient = class extends ApiClient {
1877
1895
  constructor(options) {
@@ -1973,8 +1991,15 @@ var isIncontextEditingEnabled = ({
1973
1991
  var isDevelopmentEnvironment = () => {
1974
1992
  return process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test";
1975
1993
  };
1994
+ var shouldIgnoreRedirects = ({ state }) => {
1995
+ const isNotPublished = state !== CANVAS_PUBLISHED_STATE;
1996
+ return isNotPublished ? true : void 0;
1997
+ };
1976
1998
 
1977
1999
  // src/clients/cache.ts
2000
+ var isSpecificCacheMode = (options) => {
2001
+ return "cache" in options;
2002
+ };
1978
2003
  var isStateCacheMode = (options) => {
1979
2004
  return "state" in options;
1980
2005
  };
@@ -2001,7 +2026,9 @@ var resolveCache = ({
2001
2026
  }) => {
2002
2027
  let cache2 = void 0;
2003
2028
  if (options) {
2004
- if (isStateCacheMode(options)) {
2029
+ if (isSpecificCacheMode(options)) {
2030
+ cache2 = options.cache;
2031
+ } else if (isStateCacheMode(options)) {
2005
2032
  if (options.state === CANVAS_DRAFT_STATE || options.state === CANVAS_EDITOR_STATE) {
2006
2033
  cache2 = {
2007
2034
  type: "no-cache",
@@ -2743,6 +2770,13 @@ var createTestComponentProps = ({
2743
2770
  test
2744
2771
  }) => {
2745
2772
  var _a;
2773
+ if (pageState.isPrefetch) {
2774
+ return {
2775
+ ...common,
2776
+ index: void 0,
2777
+ test
2778
+ };
2779
+ }
2746
2780
  const component = resolveComponentFromPageState({
2747
2781
  pageState,
2748
2782
  componentId
@@ -2781,6 +2815,7 @@ var applyEditableParameters = ({
2781
2815
  };
2782
2816
 
2783
2817
  // src/components/Test.tsx
2818
+ import { ClientTest } from "@uniformdev/next-app-router-client";
2784
2819
  import { createElement, Fragment } from "react";
2785
2820
 
2786
2821
  // src/components/ContextTestTransfer.tsx
@@ -2793,7 +2828,14 @@ var ContextTestTransfer = ({ event }) => {
2793
2828
  // src/components/Test.tsx
2794
2829
  var Test = ({ index, slots, test, component, context: compositionContext }) => {
2795
2830
  var _a, _b, _c, _d, _e, _f;
2796
- const indexToShow = typeof index === "number" ? (_b = (_a = slots == null ? void 0 : slots[CANVAS_TEST_SLOT]) == null ? void 0 : _a.items[index]) != null ? _b : null : null;
2831
+ if (typeof index !== "number") {
2832
+ return createElement(ClientTest, {
2833
+ slots,
2834
+ test,
2835
+ context: compositionContext
2836
+ });
2837
+ }
2838
+ const indexToShow = (_b = (_a = slots == null ? void 0 : slots[CANVAS_TEST_SLOT]) == null ? void 0 : _a.items[index]) != null ? _b : null;
2797
2839
  const event = {
2798
2840
  name: test.name,
2799
2841
  control: (_d = (_c = test.variations[index]) == null ? void 0 : _c.control) != null ? _d : false,
@@ -2850,6 +2892,9 @@ var getQuirkSerialization = () => {
2850
2892
  return true;
2851
2893
  };
2852
2894
  var getMiddlewareRuntimeCache = () => {
2895
+ if (process.env.NODE_ENV === "development" && !process.env.RUNTIME_CACHE_ENDPOINT) {
2896
+ return false;
2897
+ }
2853
2898
  if (typeof config.middlewareRuntimeCache === "boolean") {
2854
2899
  return config.middlewareRuntimeCache;
2855
2900
  }
@@ -3571,7 +3616,8 @@ var generatePossiblePageStates = ({
3571
3616
  defaultConsent: void 0,
3572
3617
  previewMode: void 0,
3573
3618
  rules: void 0,
3574
- locale
3619
+ locale,
3620
+ isPrefetch: void 0
3575
3621
  };
3576
3622
  const allStates = generateStatesRecursively(dependencyMap, void 0, initialState);
3577
3623
  return allStates.map((payload) => serializeEvaluationResult({ payload }));
@@ -3623,7 +3669,10 @@ var DefaultDataClient = class {
3623
3669
  }
3624
3670
  }
3625
3671
  const manifest = await getManifest({
3626
- cache: {
3672
+ cache: isDevelopmentEnvironment() ? {
3673
+ type: "no-cache",
3674
+ bypassCache: true
3675
+ } : {
3627
3676
  type: "force-cache"
3628
3677
  }
3629
3678
  });
@@ -3726,12 +3775,13 @@ var DefaultDataClient = class {
3726
3775
  };
3727
3776
  }
3728
3777
  async getRoutePageState(options) {
3778
+ const shouldBypassCache = options.pageState.compositionState !== CANVAS_PUBLISHED_STATE || isDevelopmentEnvironment();
3729
3779
  const routeClient = getRouteClient({
3730
- cache: options.pageState.compositionState === CANVAS_PUBLISHED_STATE ? {
3731
- type: "force-cache"
3732
- } : {
3780
+ cache: shouldBypassCache ? {
3733
3781
  type: "no-cache",
3734
3782
  bypassCache: true
3783
+ } : {
3784
+ type: "force-cache"
3735
3785
  }
3736
3786
  });
3737
3787
  const originalRoute = {
@@ -3739,7 +3789,8 @@ var DefaultDataClient = class {
3739
3789
  state: options.pageState.compositionState,
3740
3790
  withComponentIDs: true,
3741
3791
  releaseId: options.pageState.releaseId,
3742
- locale: options.pageState.locale
3792
+ locale: options.pageState.locale,
3793
+ ignoreRedirects: shouldIgnoreRedirects({ state: options.pageState.compositionState })
3743
3794
  };
3744
3795
  const resolvedRoute = await this.getRouteFromApi({
3745
3796
  source: "pageState",