@timber-js/app 0.2.0-alpha.175 → 0.2.0-alpha.177
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/_chunks/{actions-pN8r5Vnh.js → actions-O_LsyCE4.js} +3 -3
- package/dist/_chunks/{actions-pN8r5Vnh.js.map → actions-O_LsyCE4.js.map} +1 -1
- package/dist/_chunks/{cache-api-2hT5kfsr.js → cache-api-B-lhk9p4.js} +2 -2
- package/dist/_chunks/{cache-api-2hT5kfsr.js.map → cache-api-B-lhk9p4.js.map} +1 -1
- package/dist/_chunks/{cli-schema-sync-DvdvFwwE.js → cli-schema-sync-D3naS3eH.js} +2 -2
- package/dist/_chunks/{cli-schema-sync-DvdvFwwE.js.map → cli-schema-sync-D3naS3eH.js.map} +1 -1
- package/dist/_chunks/{logger-kUT0QH0K.js → logger-AWfuX-KJ.js} +1 -23
- package/dist/_chunks/logger-AWfuX-KJ.js.map +1 -0
- package/dist/_chunks/{walkers-Bv63zfAC.js → walkers-BtTlKviE.js} +2 -2
- package/dist/_chunks/{walkers-Bv63zfAC.js.map → walkers-BtTlKviE.js.map} +1 -1
- package/dist/cache/index.js +1 -1
- package/dist/cli.js +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +227 -4
- package/dist/index.js.map +1 -1
- package/dist/plugins/build-manifest.d.ts.map +1 -1
- package/dist/plugins/request-dep.d.ts +21 -0
- package/dist/plugins/request-dep.d.ts.map +1 -0
- package/dist/routing/index.js +2 -2
- package/dist/server/als-registry.d.ts +0 -26
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/build-manifest.d.ts +6 -0
- package/dist/server/build-manifest.d.ts.map +1 -1
- package/dist/server/cookie-context.d.ts.map +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/internal.js +3 -3
- package/dist/server/internal.js.map +1 -1
- package/dist/server/request-context.d.ts +0 -15
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-dep.d.ts +15 -0
- package/dist/server/request-dep.d.ts.map +1 -0
- package/dist/server/route-element-builder.d.ts.map +1 -1
- package/dist/server/rsc-entry/helpers.d.ts +6 -6
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/slot-resolver.d.ts +1 -1
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/state-tree-diff.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +2 -0
- package/src/plugins/build-manifest.ts +10 -1
- package/src/plugins/request-dep.ts +458 -0
- package/src/server/als-registry.ts +0 -44
- package/src/server/build-manifest.ts +6 -0
- package/src/server/cookie-context.ts +1 -7
- package/src/server/request-context.ts +3 -53
- package/src/server/request-dep.ts +37 -0
- package/src/server/route-element-builder.ts +2 -6
- package/src/server/rsc-entry/helpers.ts +9 -26
- package/src/server/rsc-entry/rsc-payload.ts +4 -13
- package/src/server/slot-resolver.ts +52 -46
- package/src/server/state-tree-diff.ts +5 -6
- package/dist/_chunks/logger-kUT0QH0K.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { a as __esmMin, o as __exportAll, s as __toCommonJS } from "./_chunks/dist-BA3u1z3W.js";
|
|
2
2
|
import { c as isDynamicMetadataExtension, l as isMetadataRouteServePath, r as canonicalize } from "./_chunks/canonicalize-DQHyFClh.js";
|
|
3
|
-
import { h as swallow } from "./_chunks/logger-
|
|
4
|
-
import { i as scanRoutes } from "./_chunks/cli-schema-sync-
|
|
5
|
-
import { a as generateRouteMap, c as fileHasDirective, d as getPrerenderExport, i as validateSchemaAgainstRoutes, l as fileHasExport, n as collectInterceptionRewrites, o as fileHasAnyExport, s as fileHasDefaultExport, t as collectLeafRoutes, u as fileHasStarExport } from "./_chunks/walkers-
|
|
3
|
+
import { h as swallow } from "./_chunks/logger-AWfuX-KJ.js";
|
|
4
|
+
import { i as scanRoutes } from "./_chunks/cli-schema-sync-D3naS3eH.js";
|
|
5
|
+
import { a as generateRouteMap, c as fileHasDirective, d as getPrerenderExport, i as validateSchemaAgainstRoutes, l as fileHasExport, n as collectInterceptionRewrites, o as fileHasAnyExport, s as fileHasDefaultExport, t as collectLeafRoutes, u as fileHasStarExport } from "./_chunks/walkers-BtTlKviE.js";
|
|
6
6
|
import { a as resolveAppDir, c as createNoopTimer, n as loadTimberConfigFile, o as resolveBuildDir, r as mergeFileConfig, s as resolveClientJavascript, t as createPluginContext } from "./_chunks/plugin-context---kTF5v8.js";
|
|
7
7
|
import { t as fnv1aHash } from "./_chunks/fast-hash-D6hIVt1Y.js";
|
|
8
8
|
import { t as formatSize } from "./_chunks/format-CfwjgPz9.js";
|
|
@@ -6639,7 +6639,7 @@ function timberBuildManifest(ctx) {
|
|
|
6639
6639
|
"// Auto-generated build manifest — do not edit.",
|
|
6640
6640
|
"// Production: reads manifest from globalThis (set by _timber-manifest-init.js).",
|
|
6641
6641
|
"",
|
|
6642
|
-
"const manifest = globalThis.__TIMBER_BUILD_MANIFEST__ ?? { css: {}, js: {}, modulepreload: {}, fonts: {}, metadataRouteHashes: {} };",
|
|
6642
|
+
"const manifest = globalThis.__TIMBER_BUILD_MANIFEST__ ?? { css: {}, js: {}, modulepreload: {}, fonts: {}, metadataRouteHashes: {}, requestDep: {} };",
|
|
6643
6643
|
"",
|
|
6644
6644
|
"export default manifest;"
|
|
6645
6645
|
].join("\n");
|
|
@@ -6664,6 +6664,8 @@ function timberBuildManifest(ctx) {
|
|
|
6664
6664
|
if (envName === "client") {
|
|
6665
6665
|
ctx.buildManifest = buildManifestFromBundle(bundle, resolvedBase, ctx.root);
|
|
6666
6666
|
if (ctx.routeTree) ctx.buildManifest.metadataRouteHashes = computeMetadataRouteHashes(ctx.routeTree.root);
|
|
6667
|
+
const requestDepMap = ctx.requestDepMap;
|
|
6668
|
+
if (requestDepMap) ctx.buildManifest.requestDep = requestDepMap;
|
|
6667
6669
|
if (ctx.clientJavascript.disabled) {
|
|
6668
6670
|
ctx.buildManifest.js = {};
|
|
6669
6671
|
ctx.buildManifest.modulepreload = {};
|
|
@@ -7758,6 +7760,226 @@ function timberCacheTransform(ctx) {
|
|
|
7758
7760
|
};
|
|
7759
7761
|
}
|
|
7760
7762
|
//#endregion
|
|
7763
|
+
//#region src/plugins/request-dep.ts
|
|
7764
|
+
var ACCESSOR_SOURCES = /* @__PURE__ */ new Set([
|
|
7765
|
+
"@timber-js/app/server",
|
|
7766
|
+
"next/headers",
|
|
7767
|
+
"next/headers.js"
|
|
7768
|
+
]);
|
|
7769
|
+
var ACCESSOR_NAMES = /* @__PURE__ */ new Set([
|
|
7770
|
+
"getHeaders",
|
|
7771
|
+
"getHeader",
|
|
7772
|
+
"getSearchParams",
|
|
7773
|
+
"getCookieJar",
|
|
7774
|
+
"getCookie",
|
|
7775
|
+
"headers",
|
|
7776
|
+
"cookies"
|
|
7777
|
+
]);
|
|
7778
|
+
var DEFINITION_FACTORY_SOURCES = /* @__PURE__ */ new Set(["@timber-js/app/search-params", "@timber-js/app/cookies"]);
|
|
7779
|
+
var DEFINITION_FACTORY_NAMES = /* @__PURE__ */ new Set(["defineSearchParams", "defineCookie"]);
|
|
7780
|
+
var ACCESSOR_TOKENS = [
|
|
7781
|
+
"getHeaders",
|
|
7782
|
+
"getHeader",
|
|
7783
|
+
"getSearchParams",
|
|
7784
|
+
"getCookieJar",
|
|
7785
|
+
"getCookie",
|
|
7786
|
+
"headers",
|
|
7787
|
+
"cookies",
|
|
7788
|
+
"defineSearchParams",
|
|
7789
|
+
"defineCookie",
|
|
7790
|
+
".get("
|
|
7791
|
+
];
|
|
7792
|
+
function hasRelevantToken(code) {
|
|
7793
|
+
for (const token of ACCESSOR_TOKENS) if (code.includes(token)) return true;
|
|
7794
|
+
return false;
|
|
7795
|
+
}
|
|
7796
|
+
function analyzeModule(code, program) {
|
|
7797
|
+
const facts = {
|
|
7798
|
+
callsAccessor: false,
|
|
7799
|
+
importsDefinitionFactory: false,
|
|
7800
|
+
getterCallSources: []
|
|
7801
|
+
};
|
|
7802
|
+
for (const name of ACCESSOR_NAMES) {
|
|
7803
|
+
const bindings = findImportBindings(program, ACCESSOR_SOURCES, name);
|
|
7804
|
+
if (bindings.named.size > 0 || bindings.namespaces.size > 0) {
|
|
7805
|
+
if (hasCallSite(program, bindings.named, bindings.namespaces, name)) facts.callsAccessor = true;
|
|
7806
|
+
}
|
|
7807
|
+
}
|
|
7808
|
+
for (const name of DEFINITION_FACTORY_NAMES) {
|
|
7809
|
+
const bindings = findImportBindings(program, DEFINITION_FACTORY_SOURCES, name);
|
|
7810
|
+
if (bindings.named.size > 0 || bindings.namespaces.size > 0) facts.importsDefinitionFactory = true;
|
|
7811
|
+
}
|
|
7812
|
+
for (const stmt of program.body) {
|
|
7813
|
+
if (stmt.type !== "ImportDeclaration") continue;
|
|
7814
|
+
const decl = stmt;
|
|
7815
|
+
for (const spec of decl.specifiers) if (spec.type === "ImportDefaultSpecifier" || spec.type === "ImportSpecifier") {
|
|
7816
|
+
const localName = spec.local.name;
|
|
7817
|
+
if (hasGetterCall(program, localName)) facts.getterCallSources.push(decl.source.value);
|
|
7818
|
+
}
|
|
7819
|
+
}
|
|
7820
|
+
if (facts.importsDefinitionFactory) for (const stmt of program.body) {
|
|
7821
|
+
if (stmt.type !== "VariableDeclaration") continue;
|
|
7822
|
+
for (const decl of stmt.declarations ?? []) {
|
|
7823
|
+
if (!decl.init || !decl.id) continue;
|
|
7824
|
+
const init = decl.init;
|
|
7825
|
+
if (init.type === "CallExpression") {
|
|
7826
|
+
const callee = init.callee;
|
|
7827
|
+
if (callee.type === "Identifier") {
|
|
7828
|
+
const calleeName = callee.name;
|
|
7829
|
+
for (const factoryName of DEFINITION_FACTORY_NAMES) if (findImportBindings(program, DEFINITION_FACTORY_SOURCES, factoryName).named.has(calleeName)) {
|
|
7830
|
+
const localName = decl.id.type === "Identifier" ? decl.id.name : null;
|
|
7831
|
+
if (localName && hasGetterCall(program, localName)) facts.callsAccessor = true;
|
|
7832
|
+
}
|
|
7833
|
+
}
|
|
7834
|
+
}
|
|
7835
|
+
}
|
|
7836
|
+
}
|
|
7837
|
+
return facts;
|
|
7838
|
+
}
|
|
7839
|
+
/** Check if any named/namespace binding is called as a function. */
|
|
7840
|
+
function hasCallSite(program, named, namespaces, importedName) {
|
|
7841
|
+
return walkForCall(program, named, namespaces, importedName);
|
|
7842
|
+
}
|
|
7843
|
+
function walkForCall(node, named, namespaces, importedName) {
|
|
7844
|
+
if (node.type === "CallExpression") {
|
|
7845
|
+
const callee = node.callee;
|
|
7846
|
+
if (callee.type === "Identifier" && named.has(callee.name)) return true;
|
|
7847
|
+
if (callee.type === "MemberExpression") {
|
|
7848
|
+
const member = callee;
|
|
7849
|
+
if (!member.computed && member.object.type === "Identifier" && namespaces.has(member.object.name) && member.property.type === "Identifier" && member.property.name === importedName) return true;
|
|
7850
|
+
}
|
|
7851
|
+
}
|
|
7852
|
+
for (const key of Object.keys(node)) {
|
|
7853
|
+
if (key === "type" || key === "start" || key === "end") continue;
|
|
7854
|
+
const val = node[key];
|
|
7855
|
+
if (val && typeof val === "object") {
|
|
7856
|
+
if (Array.isArray(val)) {
|
|
7857
|
+
for (const item of val) if (item && typeof item === "object" && typeof item.type === "string") {
|
|
7858
|
+
if (walkForCall(item, named, namespaces, importedName)) return true;
|
|
7859
|
+
}
|
|
7860
|
+
} else if (typeof val.type === "string") {
|
|
7861
|
+
if (walkForCall(val, named, namespaces, importedName)) return true;
|
|
7862
|
+
}
|
|
7863
|
+
}
|
|
7864
|
+
}
|
|
7865
|
+
return false;
|
|
7866
|
+
}
|
|
7867
|
+
/** Check if `localName.get(...)` appears anywhere in the module. */
|
|
7868
|
+
function hasGetterCall(node, localName) {
|
|
7869
|
+
if (node.type === "CallExpression") {
|
|
7870
|
+
const call = node;
|
|
7871
|
+
if (call.callee.type === "MemberExpression") {
|
|
7872
|
+
const member = call.callee;
|
|
7873
|
+
if (!member.computed && member.object.type === "Identifier" && member.object.name === localName && member.property.type === "Identifier" && member.property.name === "get") return true;
|
|
7874
|
+
}
|
|
7875
|
+
}
|
|
7876
|
+
for (const key of Object.keys(node)) {
|
|
7877
|
+
if (key === "type" || key === "start" || key === "end") continue;
|
|
7878
|
+
const val = node[key];
|
|
7879
|
+
if (val && typeof val === "object") {
|
|
7880
|
+
if (Array.isArray(val)) {
|
|
7881
|
+
for (const item of val) if (item && typeof item === "object" && typeof item.type === "string") {
|
|
7882
|
+
if (hasGetterCall(item, localName)) return true;
|
|
7883
|
+
}
|
|
7884
|
+
} else if (typeof val.type === "string") {
|
|
7885
|
+
if (hasGetterCall(val, localName)) return true;
|
|
7886
|
+
}
|
|
7887
|
+
}
|
|
7888
|
+
}
|
|
7889
|
+
return false;
|
|
7890
|
+
}
|
|
7891
|
+
/** Walk the module graph from an entry, returning true if any taint source is reachable. */
|
|
7892
|
+
function isReachableTaintSource(entryId, factsMap, definitionModules, getImports) {
|
|
7893
|
+
const visited = /* @__PURE__ */ new Set();
|
|
7894
|
+
const stack = [entryId];
|
|
7895
|
+
while (stack.length > 0) {
|
|
7896
|
+
const id = stack.pop();
|
|
7897
|
+
if (visited.has(id)) continue;
|
|
7898
|
+
visited.add(id);
|
|
7899
|
+
const facts = factsMap.get(id);
|
|
7900
|
+
if (facts) {
|
|
7901
|
+
if (facts.callsAccessor) return true;
|
|
7902
|
+
for (const source of facts.getterCallSources);
|
|
7903
|
+
}
|
|
7904
|
+
const imports = getImports(id);
|
|
7905
|
+
for (const imp of imports) if (!imp.startsWith("\0") && !visited.has(imp)) stack.push(imp);
|
|
7906
|
+
}
|
|
7907
|
+
for (const id of visited) {
|
|
7908
|
+
const facts = factsMap.get(id);
|
|
7909
|
+
if (!facts) continue;
|
|
7910
|
+
if (facts.getterCallSources.length === 0) continue;
|
|
7911
|
+
const imports = getImports(id);
|
|
7912
|
+
for (const imp of imports) if (definitionModules.has(imp)) return true;
|
|
7913
|
+
}
|
|
7914
|
+
return false;
|
|
7915
|
+
}
|
|
7916
|
+
var BRIDGE_KEY = Symbol.for("timber:request-dep");
|
|
7917
|
+
function timberRequestDep(ctx) {
|
|
7918
|
+
const factsMap = /* @__PURE__ */ new Map();
|
|
7919
|
+
const definitionModules = /* @__PURE__ */ new Set();
|
|
7920
|
+
const cache = /* @__PURE__ */ new Map();
|
|
7921
|
+
return {
|
|
7922
|
+
name: "timber-request-dep",
|
|
7923
|
+
applyToEnvironment(env) {
|
|
7924
|
+
return env.name === "rsc";
|
|
7925
|
+
},
|
|
7926
|
+
async transform(code, id) {
|
|
7927
|
+
if (!/\.[mc]?[jt]sx?$/.test(id) && !/\.mdx?$/.test(id)) return;
|
|
7928
|
+
if (id.startsWith("\0") || id.startsWith("virtual:")) return;
|
|
7929
|
+
if (!hasRelevantToken(code)) return;
|
|
7930
|
+
const facts = analyzeModule(code, this.parse(code));
|
|
7931
|
+
if (facts.callsAccessor || facts.importsDefinitionFactory || facts.getterCallSources.length > 0) {
|
|
7932
|
+
factsMap.set(id, facts);
|
|
7933
|
+
if (facts.importsDefinitionFactory) definitionModules.add(id);
|
|
7934
|
+
}
|
|
7935
|
+
},
|
|
7936
|
+
configureServer(server) {
|
|
7937
|
+
const resolver = (filePath) => {
|
|
7938
|
+
if (cache.has(filePath)) return cache.get(filePath);
|
|
7939
|
+
const rscEnv = server.environments?.rsc;
|
|
7940
|
+
if (!rscEnv?.moduleGraph) return true;
|
|
7941
|
+
const getImports = (moduleId) => {
|
|
7942
|
+
const mod = rscEnv.moduleGraph.getModuleById(moduleId);
|
|
7943
|
+
if (!mod) return [];
|
|
7944
|
+
const result = [];
|
|
7945
|
+
for (const imp of mod.importedModules) if (imp.id) result.push(imp.id);
|
|
7946
|
+
return result;
|
|
7947
|
+
};
|
|
7948
|
+
const result = isReachableTaintSource(filePath, factsMap, definitionModules, getImports);
|
|
7949
|
+
cache.set(filePath, result);
|
|
7950
|
+
return result;
|
|
7951
|
+
};
|
|
7952
|
+
globalThis[BRIDGE_KEY] = resolver;
|
|
7953
|
+
const clearCache = () => cache.clear();
|
|
7954
|
+
server.watcher.on("change", clearCache);
|
|
7955
|
+
server.watcher.on("add", clearCache);
|
|
7956
|
+
server.watcher.on("unlink", clearCache);
|
|
7957
|
+
},
|
|
7958
|
+
buildEnd() {
|
|
7959
|
+
if (ctx.dev) return;
|
|
7960
|
+
const getModuleInfo = this.getModuleInfo;
|
|
7961
|
+
const getImports = (moduleId) => {
|
|
7962
|
+
const info = getModuleInfo(moduleId);
|
|
7963
|
+
if (!info) return [];
|
|
7964
|
+
return [...info.importedIds ?? [], ...info.dynamicallyImportedIds ?? []];
|
|
7965
|
+
};
|
|
7966
|
+
const requestDepMap = {};
|
|
7967
|
+
if (ctx.routeTree) walkSegmentTree(ctx.routeTree.root, (filePath) => {
|
|
7968
|
+
const result = isReachableTaintSource(filePath, factsMap, definitionModules, getImports);
|
|
7969
|
+
requestDepMap[filePath] = result;
|
|
7970
|
+
});
|
|
7971
|
+
ctx.requestDepMap = requestDepMap;
|
|
7972
|
+
}
|
|
7973
|
+
};
|
|
7974
|
+
}
|
|
7975
|
+
function walkSegmentTree(node, fn) {
|
|
7976
|
+
if (node.layout) fn(node.layout.filePath);
|
|
7977
|
+
if (node.page) fn(node.page.filePath);
|
|
7978
|
+
if (node.default) fn(node.default.filePath);
|
|
7979
|
+
if (node.children) for (const child of node.children) walkSegmentTree(child, fn);
|
|
7980
|
+
if (node.slots) for (const slot of Object.values(node.slots)) walkSegmentTree(slot, fn);
|
|
7981
|
+
}
|
|
7982
|
+
//#endregion
|
|
7761
7983
|
//#region src/plugins/callsite-jsx.ts
|
|
7762
7984
|
/**
|
|
7763
7985
|
* Try to extract a static JSON-safe value from an AST expression node.
|
|
@@ -9984,6 +10206,7 @@ function timber(config) {
|
|
|
9984
10206
|
timberStaticBuild(ctx),
|
|
9985
10207
|
timberFonts(ctx),
|
|
9986
10208
|
timberMdx(ctx),
|
|
10209
|
+
timberRequestDep(ctx),
|
|
9987
10210
|
timberCacheTransform(ctx),
|
|
9988
10211
|
timberPrerenderSugar(ctx),
|
|
9989
10212
|
timberPrebuilt(ctx),
|