@toddledev/ssr
Advanced tools
Comparing version
@@ -1,6 +0,3 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.takeIncludedComponents = takeIncludedComponents; | ||
const util_1 = require("@toddledev/core/dist/utils/util"); | ||
function takeIncludedComponents({ root, projectComponents, packages = {}, includeRoot = true, }) { | ||
import { isDefined } from '@toddledev/core/dist/utils/util'; | ||
export function takeIncludedComponents({ root, projectComponents, packages = {}, includeRoot = true, }) { | ||
const components = { | ||
@@ -28,3 +25,3 @@ ...projectComponents, | ||
const nodeName = [node.package ?? packageName, node.name] | ||
.filter(util_1.isDefined) | ||
.filter(isDefined) | ||
.join('/'); | ||
@@ -35,3 +32,3 @@ if (dependencies.has(nodeName)) { | ||
const component = components[nodeName]; | ||
if (!(0, util_1.isDefined)(component)) { | ||
if (!isDefined(component)) { | ||
return; | ||
@@ -38,0 +35,0 @@ } |
@@ -1,6 +0,3 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.VOID_HTML_ELEMENTS = void 0; | ||
// See https://developer.mozilla.org/en-US/docs/Glossary/Void_element | ||
exports.VOID_HTML_ELEMENTS = [ | ||
export const VOID_HTML_ELEMENTS = [ | ||
'area', | ||
@@ -7,0 +4,0 @@ 'base', |
@@ -1,12 +0,8 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.generateCustomCodeFile = exports.hasCustomCode = void 0; | ||
exports.takeReferencedFormulasAndActions = takeReferencedFormulasAndActions; | ||
const ToddleComponent_1 = require("@toddledev/core/dist/component/ToddleComponent"); | ||
const formulaTypes_1 = require("@toddledev/core/dist/formula/formulaTypes"); | ||
const collections_1 = require("@toddledev/core/dist/utils/collections"); | ||
const util_1 = require("@toddledev/core/dist/utils/util"); | ||
function takeReferencedFormulasAndActions({ component, files, }) { | ||
import { ToddleComponent } from '@toddledev/core/dist/component/ToddleComponent'; | ||
import { isToddleFormula } from '@toddledev/core/dist/formula/formulaTypes'; | ||
import { filterObject, mapObject } from '@toddledev/core/dist/utils/collections'; | ||
import { isDefined } from '@toddledev/core/dist/utils/util'; | ||
export function takeReferencedFormulasAndActions({ component, files, }) { | ||
// If no entry file is specified or found, return all actions and formulas | ||
if (!(0, util_1.isDefined)(component)) { | ||
if (!isDefined(component)) { | ||
return { | ||
@@ -21,3 +17,3 @@ __PROJECT__: { | ||
}, | ||
...(0, collections_1.mapObject)(files.packages ?? {}, ([packageName, { actions, formulas }]) => [ | ||
...mapObject(files.packages ?? {}, ([packageName, { actions, formulas }]) => [ | ||
packageName, | ||
@@ -34,6 +30,6 @@ { | ||
const formulaRefs = new Set(); | ||
const toddleComponent = new ToddleComponent_1.ToddleComponent({ | ||
const toddleComponent = new ToddleComponent({ | ||
component: component, | ||
getComponent: (name, packageName) => { | ||
const nodeLookupKey = [packageName, name].filter(util_1.isDefined).join('/'); | ||
const nodeLookupKey = [packageName, name].filter(isDefined).join('/'); | ||
const component = packageName | ||
@@ -57,9 +53,9 @@ ? files.packages?.[packageName]?.components[name] | ||
toddleComponent.uniqueSubComponents.forEach((c) => { | ||
c.actionReferences.forEach((ref) => actionRefs.add([c.packageName, ref].filter(util_1.isDefined).join('/'))); | ||
c.formulaReferences.forEach((ref) => formulaRefs.add([c.packageName, ref].filter(util_1.isDefined).join('/'))); | ||
c.actionReferences.forEach((ref) => actionRefs.add([c.packageName, ref].filter(isDefined).join('/'))); | ||
c.formulaReferences.forEach((ref) => formulaRefs.add([c.packageName, ref].filter(isDefined).join('/'))); | ||
}); | ||
return { | ||
...(0, collections_1.mapObject)( | ||
...mapObject( | ||
// Only include packages that have referenced actions or formulas | ||
(0, collections_1.filterObject)(files.packages ?? {}, ([packageName, { actions, formulas }]) => Object.values(actions ?? {}).some((a) => actionRefs.has(`${packageName}/${a.name}`)) || | ||
filterObject(files.packages ?? {}, ([packageName, { actions, formulas }]) => Object.values(actions ?? {}).some((a) => actionRefs.has(`${packageName}/${a.name}`)) || | ||
Object.values(formulas ?? {}).some((f) => formulaRefs.has(`${packageName}/${f.name}`))), | ||
@@ -70,5 +66,5 @@ // Only include the actions and formulas that are referenced | ||
{ | ||
actions: (0, collections_1.filterObject)(actions ?? {}, ([_, a]) => typeof a.name === 'string' && | ||
actions: filterObject(actions ?? {}, ([_, a]) => typeof a.name === 'string' && | ||
actionRefs.has(`${packageName}/${a.name}`)), | ||
formulas: (0, collections_1.filterObject)(formulas ?? {}, ([_, f]) => typeof f.name === 'string' && | ||
formulas: filterObject(formulas ?? {}, ([_, f]) => typeof f.name === 'string' && | ||
formulaRefs.has(`${packageName}/${f.name}`)), | ||
@@ -87,9 +83,8 @@ }, | ||
} | ||
const hasCustomCode = (component, files) => { | ||
export const hasCustomCode = (component, files) => { | ||
const code = takeReferencedFormulasAndActions({ component, files }); | ||
return Object.values(code).some((c) => Object.keys(c.actions).length > 0 || Object.keys(c.formulas).length > 0); | ||
}; | ||
exports.hasCustomCode = hasCustomCode; | ||
const generateCustomCodeFile = ({ code, componentName, projectId, }) => { | ||
const v2ActionCode = (0, collections_1.mapObject)((0, collections_1.filterObject)(code, ([_, c]) => Object.values(c.actions).some((a) => a.version === 2)), ([packageName, c]) => [ | ||
export const generateCustomCodeFile = ({ code, componentName, projectId, }) => { | ||
const v2ActionCode = mapObject(filterObject(code, ([_, c]) => Object.values(c.actions).some((a) => a.version === 2)), ([packageName, c]) => [ | ||
// A small hack to group project actions/formulas under the project short id | ||
@@ -100,5 +95,5 @@ // TS doesn't let us index an object by a generic, hence this hack | ||
]); | ||
const v2FormulaCode = (0, collections_1.mapObject)((0, collections_1.filterObject)(code, ([_, c]) => Object.values(c.formulas).some( | ||
const v2FormulaCode = mapObject(filterObject(code, ([_, c]) => Object.values(c.formulas).some( | ||
// Ignore legacy code formulas | ||
(f) => (0, formulaTypes_1.isToddleFormula)(f) || f.version === 2)), ([packageName, c]) => [ | ||
(f) => isToddleFormula(f) || f.version === 2)), ([packageName, c]) => [ | ||
// A small hack to group project actions/formulas under the project short id | ||
@@ -128,3 +123,3 @@ // TS doesn't let us index an object by a generic, hence this hack | ||
${Object.values(code.__PROJECT__.formulas) | ||
.filter((a) => !(0, formulaTypes_1.isToddleFormula)(a) && | ||
.filter((a) => !isToddleFormula(a) && | ||
typeof a.name === 'string' && | ||
@@ -157,4 +152,4 @@ a.version === undefined) | ||
${Object.values(formulas) | ||
.filter((f) => (0, formulaTypes_1.isToddleFormula)(f) || f.version === 2) | ||
.map((f) => (0, formulaTypes_1.isToddleFormula)(f) | ||
.filter((f) => isToddleFormula(f) || f.version === 2) | ||
.map((f) => isToddleFormula(f) | ||
? `"${f.name}": { | ||
@@ -176,3 +171,2 @@ arguments: ${JSON.stringify(f.arguments)}, | ||
}; | ||
exports.generateCustomCodeFile = generateCustomCodeFile; | ||
/** | ||
@@ -179,0 +173,0 @@ * Removes non-alphanumeric characters except for _ from a function name |
@@ -1,3 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
export {}; | ||
//# sourceMappingURL=api.js.map |
@@ -1,7 +0,3 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.toEncodedText = exports.escapeAttrValue = void 0; | ||
exports.getNodeAttrs = getNodeAttrs; | ||
const formula_1 = require("@toddledev/core/dist/formula/formula"); | ||
const util_1 = require("@toddledev/core/dist/utils/util"); | ||
import { applyFormula } from '@toddledev/core/dist/formula/formula'; | ||
import { isDefined, toBoolean } from '@toddledev/core/dist/utils/util'; | ||
const REGEXP_QUOTE = /"/g; | ||
@@ -11,4 +7,4 @@ const REGEXP_LT = /</g; | ||
const validAttrTypes = ['string', 'number', 'boolean']; | ||
const escapeAttrValue = (value) => { | ||
if (!(0, util_1.isDefined)(value) || !validAttrTypes.includes(typeof value)) { | ||
export const escapeAttrValue = (value) => { | ||
if (!isDefined(value) || !validAttrTypes.includes(typeof value)) { | ||
return ''; | ||
@@ -18,3 +14,2 @@ } | ||
}; | ||
exports.escapeAttrValue = escapeAttrValue; | ||
const escapeQuote = (value) => { | ||
@@ -29,3 +24,3 @@ return value.replace(REGEXP_QUOTE, '"'); | ||
*/ | ||
const toEncodedText = (str) => { | ||
export const toEncodedText = (str) => { | ||
return str | ||
@@ -39,7 +34,6 @@ .replaceAll('&', '&') | ||
}; | ||
exports.toEncodedText = toEncodedText; | ||
function getNodeAttrs({ node, data, component, packageName, env, toddle, }) { | ||
export function getNodeAttrs({ node, data, component, packageName, env, toddle, }) { | ||
const { style, ...restAttrs } = node.attrs; | ||
const nodeAttrs = Object.entries(restAttrs).reduce((appliedAttributes, [name, attrValue]) => { | ||
const value = (0, formula_1.applyFormula)(attrValue, { | ||
const value = applyFormula(attrValue, { | ||
data, | ||
@@ -51,8 +45,8 @@ component, | ||
}); | ||
if ((0, util_1.toBoolean)(value)) { | ||
appliedAttributes.push(`${name}="${(0, exports.escapeAttrValue)(value)}"`); | ||
if (toBoolean(value)) { | ||
appliedAttributes.push(`${name}="${escapeAttrValue(value)}"`); | ||
} | ||
return appliedAttributes; | ||
}, []); | ||
const styleVariables = Object.values(node['style-variables'] ?? {}).map(({ name, formula, unit }) => `--${name}: ${String((0, formula_1.applyFormula)(formula, { | ||
const styleVariables = Object.values(node['style-variables'] ?? {}).map(({ name, formula, unit }) => `--${name}: ${String(applyFormula(formula, { | ||
data, | ||
@@ -68,3 +62,3 @@ component, | ||
? [ | ||
(0, formula_1.applyFormula)(style, { | ||
applyFormula(style, { | ||
data, | ||
@@ -84,3 +78,3 @@ component, | ||
if (styles.length > 0) { | ||
return [...nodeAttrs, `style="${(0, exports.escapeAttrValue)(styles)};"`].join(' '); | ||
return [...nodeAttrs, `style="${escapeAttrValue(styles)};"`].join(' '); | ||
} | ||
@@ -87,0 +81,0 @@ return nodeAttrs.join(' '); |
@@ -1,12 +0,9 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.renderPageBody = void 0; | ||
const ToddleComponent_1 = require("@toddledev/core/dist/component/ToddleComponent"); | ||
const formula_1 = require("@toddledev/core/dist/formula/formula"); | ||
const className_1 = require("@toddledev/core/dist/styling/className"); | ||
const collections_1 = require("@toddledev/core/dist/utils/collections"); | ||
const util_1 = require("@toddledev/core/dist/utils/util"); | ||
const xss_1 = require("xss"); | ||
const const_1 = require("../const"); | ||
const attributes_1 = require("./attributes"); | ||
import { ToddleComponent } from '@toddledev/core/dist/component/ToddleComponent'; | ||
import { applyFormula } from '@toddledev/core/dist/formula/formula'; | ||
import { getClassName, toValidClassName, } from '@toddledev/core/dist/styling/className'; | ||
import { mapValues } from '@toddledev/core/dist/utils/collections'; | ||
import { isDefined, toBoolean } from '@toddledev/core/dist/utils/util'; | ||
import { escapeAttrValue } from 'xss'; | ||
import { VOID_HTML_ELEMENTS } from '../const'; | ||
import { getNodeAttrs, toEncodedText } from './attributes'; | ||
const renderComponent = async ({ apiCache, children, component, data, env, evaluateComponentApis, files, toddle, includedComponents, instance, packageName, projectId, req, updateApiCache, }) => { | ||
@@ -25,3 +22,3 @@ const renderNode = async ({ id, node, data, packageName, isComponentRootNode = false, }) => { | ||
if (node.repeat) { | ||
const items = (0, formula_1.applyFormula)(node.repeat, formulaContext); | ||
const items = applyFormula(node.repeat, formulaContext); | ||
if (!Array.isArray(items)) { | ||
@@ -44,3 +41,3 @@ return ''; | ||
if (node.condition && | ||
!(0, util_1.toBoolean)((0, formula_1.applyFormula)(node.condition, formulaContext))) { | ||
!toBoolean(applyFormula(node.condition, formulaContext))) { | ||
return ''; | ||
@@ -50,3 +47,3 @@ } | ||
case 'text': { | ||
return `<span data-node-type="text" data-node-id="${id}">${(0, attributes_1.toEncodedText)(String((0, formula_1.applyFormula)(node.value, formulaContext)))}</span>`; | ||
return `<span data-node-type="text" data-node-id="${id}">${toEncodedText(String(applyFormula(node.value, formulaContext)))}</span>`; | ||
} | ||
@@ -72,3 +69,3 @@ case 'slot': { | ||
} | ||
const nodeAttrs = (0, attributes_1.getNodeAttrs)({ | ||
const nodeAttrs = getNodeAttrs({ | ||
node, | ||
@@ -81,5 +78,5 @@ data, | ||
}); | ||
const classHash = (0, className_1.getClassName)([node.style, node.variants]); | ||
const classHash = getClassName([node.style, node.variants]); | ||
let classList = Object.entries(node.classes) | ||
.filter(([_, { formula }]) => (0, util_1.toBoolean)((0, formula_1.applyFormula)(formula, formulaContext))) | ||
.filter(([_, { formula }]) => toBoolean(applyFormula(formula, formulaContext))) | ||
.map(([className]) => className) | ||
@@ -89,3 +86,3 @@ .join(' '); | ||
Object.entries(instance).forEach(([key, value]) => { | ||
classList += ' ' + (0, className_1.toValidClassName)(`${key}:${value}`); | ||
classList += ' ' + toValidClassName(`${key}:${value}`); | ||
}); | ||
@@ -109,3 +106,3 @@ } | ||
if (textNode?.type === 'text') { | ||
innerHTML = String((0, formula_1.applyFormula)(textNode.value, formulaContext)); | ||
innerHTML = String(applyFormula(textNode.value, formulaContext)); | ||
} | ||
@@ -117,11 +114,11 @@ } | ||
const nodeClasses = `${classHash} ${classList}`.trim(); | ||
if (!const_1.VOID_HTML_ELEMENTS.includes(tag)) { | ||
return `<${tag} ${nodeAttrs} data-node-id="${(0, xss_1.escapeAttrValue)(id)}" class="${(0, xss_1.escapeAttrValue)(nodeClasses)}">${innerHTML}</${tag}>`; | ||
if (!VOID_HTML_ELEMENTS.includes(tag)) { | ||
return `<${tag} ${nodeAttrs} data-node-id="${escapeAttrValue(id)}" class="${escapeAttrValue(nodeClasses)}">${innerHTML}</${tag}>`; | ||
} | ||
else { | ||
return `<${tag} ${nodeAttrs} data-node-id="${(0, xss_1.escapeAttrValue)(id)}" class="${(0, xss_1.escapeAttrValue)(nodeClasses)}" />`; | ||
return `<${tag} ${nodeAttrs} data-node-id="${escapeAttrValue(id)}" class="${escapeAttrValue(nodeClasses)}" />`; | ||
} | ||
} | ||
case 'component': { | ||
const attrs = (0, collections_1.mapValues)(node.attrs, (formula) => (0, formula_1.applyFormula)(formula, formulaContext)); | ||
const attrs = mapValues(node.attrs, (formula) => applyFormula(formula, formulaContext)); | ||
const contexts = { | ||
@@ -133,3 +130,3 @@ ...data.Contexts, | ||
key, | ||
(0, formula_1.applyFormula)(formula.formula, formulaContext), | ||
applyFormula(formula.formula, formulaContext), | ||
])), | ||
@@ -148,5 +145,5 @@ }; | ||
} | ||
if (!(0, util_1.isDefined)(_childComponent)) { | ||
if (!isDefined(_childComponent)) { | ||
console.warn(`Unable to find component ${[packageName, node.name] | ||
.filter(util_1.isDefined) | ||
.filter(isDefined) | ||
.join('/')} in files`); | ||
@@ -160,7 +157,7 @@ return ''; | ||
const apis = await evaluateComponentApis({ | ||
component: new ToddleComponent_1.ToddleComponent({ | ||
component: new ToddleComponent({ | ||
component: childComponent, | ||
getComponent: (name, packageName) => { | ||
const nodeLookupKey = [packageName, name] | ||
.filter(util_1.isDefined) | ||
.filter(isDefined) | ||
.join('/'); | ||
@@ -187,4 +184,4 @@ const component = packageName | ||
Contexts: contexts, | ||
Variables: (0, collections_1.mapValues)(childComponent.variables, ({ initialValue }) => { | ||
return (0, formula_1.applyFormula)(initialValue, formulaContext); | ||
Variables: mapValues(childComponent.variables, ({ initialValue }) => { | ||
return applyFormula(initialValue, formulaContext); | ||
}), | ||
@@ -213,3 +210,3 @@ Apis: {}, | ||
key, | ||
(0, formula_1.applyFormula)(formula.formula, { | ||
applyFormula(formula.formula, { | ||
component: childComponent, | ||
@@ -224,3 +221,3 @@ package: _packageName, | ||
key, | ||
(0, formula_1.applyFormula)(formula.formula, { | ||
applyFormula(formula.formula, { | ||
data: { | ||
@@ -239,4 +236,4 @@ Attributes: attrs, | ||
Attributes: attrs, | ||
Variables: (0, collections_1.mapValues)(childComponent.variables, ({ initialValue }) => { | ||
return (0, formula_1.applyFormula)(initialValue, { | ||
Variables: mapValues(childComponent.variables, ({ initialValue }) => { | ||
return applyFormula(initialValue, { | ||
data: { | ||
@@ -306,4 +303,4 @@ Attributes: attrs, | ||
Contexts: contexts, | ||
Variables: (0, collections_1.mapValues)(component.variables, ({ initialValue }) => { | ||
return (0, formula_1.applyFormula)(initialValue, { | ||
Variables: mapValues(component.variables, ({ initialValue }) => { | ||
return applyFormula(initialValue, { | ||
...formulaContext, | ||
@@ -324,3 +321,3 @@ data: { | ||
key, | ||
(0, formula_1.applyFormula)(formula.formula, { | ||
applyFormula(formula.formula, { | ||
...formulaContext, | ||
@@ -351,3 +348,3 @@ data, | ||
*/ | ||
const renderPageBody = async ({ component, env, evaluateComponentApis, files, formulaContext, includedComponents, req, projectId, }) => { | ||
export const renderPageBody = async ({ component, env, evaluateComponentApis, files, formulaContext, includedComponents, req, projectId, }) => { | ||
const apiCache = {}; | ||
@@ -380,3 +377,2 @@ const updateApiCache = (key, value) => (apiCache[key] = value); | ||
}; | ||
exports.renderPageBody = renderPageBody; | ||
//# sourceMappingURL=components.js.map |
@@ -1,10 +0,6 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getRequestCookies = void 0; | ||
const util_1 = require("@toddledev/core/dist/utils/util"); | ||
const cookie_1 = require("cookie"); | ||
const getRequestCookies = (req) => Object.fromEntries(Object.entries((0, cookie_1.parse)(req.headers.get('cookie') ?? '')).filter( | ||
import { isDefined } from '@toddledev/core/dist/utils/util'; | ||
import { parse } from 'cookie'; | ||
export const getRequestCookies = (req) => Object.fromEntries(Object.entries(parse(req.headers.get('cookie') ?? '')).filter( | ||
// Ensure that both key and value are defined | ||
(kv) => (0, util_1.isDefined)(kv[0]) && (0, util_1.isDefined)(kv[1]))); | ||
exports.getRequestCookies = getRequestCookies; | ||
(kv) => isDefined(kv[0]) && isDefined(kv[1]))); | ||
//# sourceMappingURL=cookies.js.map |
@@ -1,15 +0,8 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.initIsEqual = void 0; | ||
const fast_deep_equal_1 = __importDefault(require("fast-deep-equal")); | ||
const initIsEqual = () => { | ||
import fastDeepEqual from 'fast-deep-equal'; | ||
export const initIsEqual = () => { | ||
const toddle = { | ||
isEqual: fast_deep_equal_1.default, | ||
isEqual: fastDeepEqual, | ||
}; | ||
globalThis.toddle = toddle; | ||
}; | ||
exports.initIsEqual = initIsEqual; | ||
//# sourceMappingURL=equals.js.map |
@@ -1,6 +0,3 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getFontCssUrl = void 0; | ||
const collections_1 = require("@toddledev/core/dist/utils/collections"); | ||
const getFontCssUrl = ({ fonts, baseForAbsoluteUrls, basePath = '/.toddle/fonts/stylesheet/css2', }) => { | ||
import { easySort } from '@toddledev/core/dist/utils/collections'; | ||
export const getFontCssUrl = ({ fonts, baseForAbsoluteUrls, basePath = '/.toddle/fonts/stylesheet/css2', }) => { | ||
if (fonts.length === 0) { | ||
@@ -12,3 +9,3 @@ return; | ||
for (const font of fonts) { | ||
const sortedWeights = (0, collections_1.easySort)(font.variants.filter((v) => !Number.isNaN(Number(v.weight))), (v) => Number(v.weight)); | ||
const sortedWeights = easySort(font.variants.filter((v) => !Number.isNaN(Number(v.weight))), (v) => Number(v.weight)); | ||
if (sortedWeights.length === 0) { | ||
@@ -70,3 +67,2 @@ continue; | ||
}; | ||
exports.getFontCssUrl = getFontCssUrl; | ||
//# sourceMappingURL=fonts.js.map |
@@ -1,45 +0,9 @@ | ||
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || (function () { | ||
var ownKeys = function(o) { | ||
ownKeys = Object.getOwnPropertyNames || function (o) { | ||
var ar = []; | ||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; | ||
return ar; | ||
}; | ||
return ownKeys(o); | ||
}; | ||
return function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
})(); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.serverEnv = exports.getParameters = exports.getDataUrlParameters = exports.getServerToddleObject = exports.getPageFormulaContext = void 0; | ||
const formula_1 = require("@toddledev/core/dist/formula/formula"); | ||
const formulaTypes_1 = require("@toddledev/core/dist/formula/formulaTypes"); | ||
const collections_1 = require("@toddledev/core/dist/utils/collections"); | ||
const util_1 = require("@toddledev/core/dist/utils/util"); | ||
const libFormulas = __importStar(require("@toddledev/std-lib/dist/formulas")); | ||
const routing_1 = require("../routing/routing"); | ||
const cookies_1 = require("./cookies"); | ||
const request_1 = require("./request"); | ||
import { applyFormula } from '@toddledev/core/dist/formula/formula'; | ||
import { isToddleFormula } from '@toddledev/core/dist/formula/formulaTypes'; | ||
import { mapValues } from '@toddledev/core/dist/utils/collections'; | ||
import { isDefined } from '@toddledev/core/dist/utils/util'; | ||
import * as libFormulas from '@toddledev/std-lib/dist/formulas'; | ||
import { getPathSegments } from '../routing/routing'; | ||
import { getRequestCookies } from './cookies'; | ||
import { escapeSearchParameters } from './request'; | ||
/** | ||
@@ -49,5 +13,5 @@ * Builds a FormulaContext that can be used to evaluate formulas for a page component | ||
*/ | ||
const getPageFormulaContext = ({ branchName, component, req, logErrors, files, }) => { | ||
const env = (0, exports.serverEnv)({ req, branchName, logErrors }); | ||
const { searchParamsWithDefaults, hash, combinedParams, url } = (0, exports.getParameters)({ route: component.route, req }); | ||
export const getPageFormulaContext = ({ branchName, component, req, logErrors, files, }) => { | ||
const env = serverEnv({ req, branchName, logErrors }); | ||
const { searchParamsWithDefaults, hash, combinedParams, url } = getParameters({ route: component.route, req }); | ||
const formulaContext = { | ||
@@ -66,3 +30,3 @@ data: { | ||
// in case of naming collisions | ||
'URL parameters': (0, exports.getDataUrlParameters)({ route: component.route, req }), | ||
'URL parameters': getDataUrlParameters({ route: component.route, req }), | ||
Apis: {}, | ||
@@ -74,11 +38,10 @@ }, | ||
env, | ||
toddle: (0, exports.getServerToddleObject)(files), | ||
toddle: getServerToddleObject(files), | ||
}; | ||
formulaContext.data.Variables = (0, collections_1.mapValues)(component.variables, ({ initialValue }) => { | ||
return (0, formula_1.applyFormula)(initialValue, formulaContext); | ||
formulaContext.data.Variables = mapValues(component.variables, ({ initialValue }) => { | ||
return applyFormula(initialValue, formulaContext); | ||
}); | ||
return formulaContext; | ||
}; | ||
exports.getPageFormulaContext = getPageFormulaContext; | ||
const getServerToddleObject = (files) => { | ||
export const getServerToddleObject = (files) => { | ||
const coreFormulas = Object.fromEntries(Object.entries(libFormulas).map(([name, module]) => [ | ||
@@ -92,3 +55,3 @@ '@toddle/' + name, | ||
let formula; | ||
if ((0, util_1.isDefined)(packageName)) { | ||
if (isDefined(packageName)) { | ||
formula = files.packages?.[packageName]?.formulas?.[name]; | ||
@@ -99,3 +62,3 @@ } | ||
} | ||
if (formula && (0, formulaTypes_1.isToddleFormula)(formula)) { | ||
if (formula && isToddleFormula(formula)) { | ||
return formula; | ||
@@ -107,5 +70,4 @@ } | ||
}; | ||
exports.getServerToddleObject = getServerToddleObject; | ||
const getDataUrlParameters = ({ route, req, }) => { | ||
const { searchParamsWithDefaults, combinedParams } = (0, exports.getParameters)({ | ||
export const getDataUrlParameters = ({ route, req, }) => { | ||
const { searchParamsWithDefaults, combinedParams } = getParameters({ | ||
route, | ||
@@ -119,7 +81,6 @@ req, | ||
}; | ||
exports.getDataUrlParameters = getDataUrlParameters; | ||
const getParameters = ({ route, req, }) => { | ||
export const getParameters = ({ route, req, }) => { | ||
const url = new URL(req.url); | ||
const searchParams = [ | ||
...(0, request_1.escapeSearchParameters)(url.searchParams).entries(), | ||
...escapeSearchParameters(url.searchParams).entries(), | ||
].reduce((params, [key, val]) => ({ | ||
@@ -129,6 +90,6 @@ ...params, | ||
}), {}); | ||
const pathSegments = (0, routing_1.getPathSegments)(url); | ||
const pathSegments = getPathSegments(url); | ||
const pathParams = route?.path.reduce((prev, param, index) => { | ||
if (param.type === 'param') { | ||
if ((0, util_1.isDefined)(pathSegments[index]) && | ||
if (isDefined(pathSegments[index]) && | ||
typeof pathSegments[index] === 'string') { | ||
@@ -156,4 +117,3 @@ return { ...prev, [param.name]: pathSegments[index] }; | ||
}; | ||
exports.getParameters = getParameters; | ||
const serverEnv = ({ branchName, req, logErrors, }) => ({ | ||
export const serverEnv = ({ branchName, req, logErrors, }) => ({ | ||
branchName: branchName, | ||
@@ -164,3 +124,3 @@ // isServer will be true for SSR + proxied requests | ||
headers: Object.fromEntries(req.headers.entries()), | ||
cookies: (0, cookies_1.getRequestCookies)(req), | ||
cookies: getRequestCookies(req), | ||
url: req.url, | ||
@@ -170,3 +130,2 @@ }, | ||
}); | ||
exports.serverEnv = serverEnv; | ||
//# sourceMappingURL=formulaContext.js.map |
@@ -11,3 +11,3 @@ import { HeadTagTypes } from '@toddledev/core/dist/component/component.types'; | ||
*/ | ||
export declare const getHeadItems: ({ cacheBuster, context, cssBasePath, files, page, project, theme, url, }: { | ||
export declare const getHeadItems: ({ cacheBuster, context, cssBasePath, page, resetStylesheetPath, pageStylesheetPath, files, project, theme, url, }: { | ||
cacheBuster?: string; | ||
@@ -18,2 +18,4 @@ context: FormulaContext; | ||
page: ToddleComponent<string>; | ||
resetStylesheetPath?: string; | ||
pageStylesheetPath?: string; | ||
project: ToddleProject; | ||
@@ -20,0 +22,0 @@ theme: OldTheme | Theme; |
@@ -1,20 +0,17 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.defaultHeadOrdering = exports.renderHeadItems = exports.getHeadItems = void 0; | ||
const component_types_1 = require("@toddledev/core/dist/component/component.types"); | ||
const formula_1 = require("@toddledev/core/dist/formula/formula"); | ||
const collections_1 = require("@toddledev/core/dist/utils/collections"); | ||
const url_1 = require("@toddledev/core/dist/utils/url"); | ||
const util_1 = require("@toddledev/core/dist/utils/util"); | ||
const const_1 = require("../const"); | ||
const attributes_1 = require("../rendering/attributes"); | ||
const media_1 = require("../utils/media"); | ||
const nanoid_1 = require("../utils/nanoid"); | ||
const fonts_1 = require("./fonts"); | ||
const html_1 = require("./html"); | ||
const speculation_1 = require("./speculation"); | ||
import { HeadTagTypes } from '@toddledev/core/dist/component/component.types'; | ||
import { applyFormula } from '@toddledev/core/dist/formula/formula'; | ||
import { easySort } from '@toddledev/core/dist/utils/collections'; | ||
import { validateUrl } from '@toddledev/core/dist/utils/url'; | ||
import { isDefined } from '@toddledev/core/dist/utils/util'; | ||
import { VOID_HTML_ELEMENTS } from '../const'; | ||
import { escapeAttrValue } from '../rendering/attributes'; | ||
import { isCloudflareImagePath } from '../utils/media'; | ||
import { nanoid } from '../utils/nanoid'; | ||
import { getFontCssUrl } from './fonts'; | ||
import { getCharset } from './html'; | ||
import { defaultSpeculationRules } from './speculation'; | ||
/** | ||
* Returns all head items for a given page | ||
*/ | ||
const getHeadItems = ({ cacheBuster, context, cssBasePath = '/.toddle/fonts/stylesheet/css2', files, page, project, theme, url, }) => { | ||
export const getHeadItems = ({ cacheBuster, context, cssBasePath = '/.toddle/fonts/stylesheet/css2', page, resetStylesheetPath = '/_static/reset.css', pageStylesheetPath = `/.toddle/stylesheet/${page.name}.css`, files, project, theme, url, }) => { | ||
const pageInfo = page.route?.info; | ||
@@ -44,3 +41,3 @@ const title = getPageTitle({ | ||
if (theme.fonts.length > 0) { | ||
const fontStylesheetUrl = (0, fonts_1.getFontCssUrl)({ | ||
const fontStylesheetUrl = getFontCssUrl({ | ||
fonts: theme.fonts, | ||
@@ -54,3 +51,3 @@ basePath: cssBasePath, | ||
// See https://fonts.google.com/selection/embed | ||
`<link href="${(0, attributes_1.escapeAttrValue)(fontStylesheetUrl.swap.toString())}" rel="stylesheet" />`, | ||
`<link href="${escapeAttrValue(fontStylesheetUrl.swap.toString())}" rel="stylesheet" />`, | ||
]); | ||
@@ -60,4 +57,3 @@ } | ||
} | ||
const stylesheetUrl = urlWithCacheBuster('/_static/reset.css', cacheBuster); | ||
const charset = (0, html_1.getCharset)({ pageInfo, formulaContext: context }); | ||
const charset = getCharset({ pageInfo, formulaContext: context }); | ||
const descriptionItems = []; | ||
@@ -68,7 +64,7 @@ if (typeof description === 'string') { | ||
'meta:description', | ||
`<meta name="description" content="${(0, attributes_1.escapeAttrValue)(description)}" />`, | ||
`<meta name="description" content="${escapeAttrValue(description)}" />`, | ||
]); | ||
descriptionItems.push([ | ||
'meta:og:description', | ||
`<meta property="og:description" content="${(0, attributes_1.escapeAttrValue)(description)}" />`, | ||
`<meta property="og:description" content="${escapeAttrValue(description)}" />`, | ||
]); | ||
@@ -79,9 +75,12 @@ } | ||
'link:reset', | ||
// The reset stylesheet should be loaded asap to avoid any flickering | ||
`<link rel="stylesheet" fetchpriority="high" href="${(0, attributes_1.escapeAttrValue)(stylesheetUrl)}" />`, | ||
`<link rel="stylesheet" fetchpriority="high" href="${escapeAttrValue(urlWithCacheBuster(resetStylesheetPath, cacheBuster))}" />`, | ||
], | ||
[ | ||
'link:page', | ||
`<link rel="stylesheet" fetchpriority="high" href="${escapeAttrValue(urlWithCacheBuster(pageStylesheetPath, cacheBuster))}" />`, | ||
], | ||
...preloadFonts, | ||
// Initialize default head items (meta + links) | ||
// these might be overwritten by custom tags later | ||
['meta:charset', `<meta charset="${(0, attributes_1.escapeAttrValue)(charset)}" />`], | ||
['meta:charset', `<meta charset="${escapeAttrValue(charset)}" />`], | ||
[ | ||
@@ -95,7 +94,7 @@ 'meta:viewport', | ||
'meta:og:title', | ||
`<meta property="og:title" content="${(0, attributes_1.escapeAttrValue)(title)}" />`, | ||
`<meta property="og:title" content="${escapeAttrValue(title)}" />`, | ||
], | ||
[ | ||
'meta:apple-mobile-web-app-title', | ||
`<meta name="apple-mobile-web-app-title" content="${(0, attributes_1.escapeAttrValue)(title)}">`, | ||
`<meta name="apple-mobile-web-app-title" content="${escapeAttrValue(title)}">`, | ||
], | ||
@@ -107,11 +106,11 @@ // Description + og:description | ||
'meta:og:url', | ||
`<meta property="og:url" content="${(0, attributes_1.escapeAttrValue)(url.href)}" />`, | ||
`<meta property="og:url" content="${escapeAttrValue(url.href)}" />`, | ||
], | ||
[ | ||
'meta:application-name', | ||
`<meta name="application-name" content="${project.short_id === 'toddle' ? 'toddle' : (0, attributes_1.escapeAttrValue)(project.name)}">`, | ||
`<meta name="application-name" content="${project.short_id === 'toddle' ? 'toddle' : escapeAttrValue(project.name)}">`, | ||
], | ||
[ | ||
'script:speculationrules', | ||
`<script type="speculationrules">${JSON.stringify(speculation_1.defaultSpeculationRules)}</script>`, | ||
`<script type="speculationrules">${JSON.stringify(defaultSpeculationRules)}</script>`, | ||
], | ||
@@ -122,11 +121,11 @@ ]); | ||
// the thumbnail will be overwritten by the user's og:image | ||
const thumbnailUrl = (0, media_1.isCloudflareImagePath)(project.thumbnail.path) | ||
const thumbnailUrl = isCloudflareImagePath(project.thumbnail.path) | ||
? `${url.origin}${project.thumbnail.path}/256` | ||
: project.thumbnail.path; | ||
headItems.set('meta:og:image', `<meta property="og:image" content="${(0, attributes_1.escapeAttrValue)(`${thumbnailUrl}`)}" />`); | ||
headItems.set('meta:og:image', `<meta property="og:image" content="${escapeAttrValue(`${thumbnailUrl}`)}" />`); | ||
} | ||
const manifestUrl = (0, url_1.validateUrl)((0, formula_1.applyFormula)(files.config?.meta?.manifest?.formula, context)); | ||
const manifestUrl = validateUrl(applyFormula(files.config?.meta?.manifest?.formula, context)); | ||
if (manifestUrl) { | ||
const manifestUrl = urlWithCacheBuster('/manifest.json', cacheBuster); | ||
headItems.set('link:manifest', `<link rel="manifest" href="${(0, attributes_1.escapeAttrValue)(manifestUrl)}">`); | ||
headItems.set('link:manifest', `<link rel="manifest" href="${escapeAttrValue(manifestUrl)}">`); | ||
} | ||
@@ -143,14 +142,14 @@ else { | ||
const icon = files.config?.meta?.icon; | ||
if ((0, util_1.isDefined)(icon)) { | ||
const iconPath = (0, formula_1.applyFormula)(icon.formula, context); | ||
if ((0, util_1.isDefined)(iconPath) && typeof iconPath === 'string') { | ||
if ((0, media_1.isCloudflareImagePath)(iconPath)) { | ||
if (isDefined(icon)) { | ||
const iconPath = applyFormula(icon.formula, context); | ||
if (isDefined(iconPath) && typeof iconPath === 'string') { | ||
if (isCloudflareImagePath(iconPath)) { | ||
// If the icon is a cloudflare image path, we add the different sizes | ||
const basePath = iconPath.split('/').slice(0, -1).join('/'); | ||
headItems.set('link:icon:16', `<link rel="icon" sizes="16x16" href="${(0, attributes_1.escapeAttrValue)(`${basePath}/16`)}" />`); | ||
headItems.set('link:icon:32', `<link rel="icon" sizes="32x32" href="${(0, attributes_1.escapeAttrValue)(`${basePath}/32`)}" />`); | ||
headItems.set('link:icon', `<link rel="shortcut icon" href="${(0, attributes_1.escapeAttrValue)(`${basePath}/48`)}" />`); | ||
headItems.set('link:icon:16', `<link rel="icon" sizes="16x16" href="${escapeAttrValue(`${basePath}/16`)}" />`); | ||
headItems.set('link:icon:32', `<link rel="icon" sizes="32x32" href="${escapeAttrValue(`${basePath}/32`)}" />`); | ||
headItems.set('link:icon', `<link rel="shortcut icon" href="${escapeAttrValue(`${basePath}/48`)}" />`); | ||
} | ||
else { | ||
headItems.set('link:icon', `<link rel="icon" href="${(0, attributes_1.escapeAttrValue)(iconPath)}" />`); | ||
headItems.set('link:icon', `<link rel="icon" href="${escapeAttrValue(iconPath)}" />`); | ||
} | ||
@@ -170,3 +169,3 @@ } | ||
// Use emoji as icon | ||
headItems.set('link:icon', `<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>${(0, attributes_1.escapeAttrValue)(project.emoji)}</text></svg>">`); | ||
headItems.set('link:icon', `<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>${escapeAttrValue(project.emoji)}</text></svg>">`); | ||
} | ||
@@ -181,7 +180,7 @@ headItems.set('link:mask-icon', '<link rel="mask-icon" href="https://raw.githubusercontent.com/toddledev/resources/main/icons/safari-pinned-tab.svg" color="#171717">'); | ||
Object.entries(pageInfo.meta).forEach(([id, metaEntry]) => { | ||
if (Object.values(component_types_1.HeadTagTypes).includes(metaEntry.tag)) { | ||
if (Object.values(HeadTagTypes).includes(metaEntry.tag)) { | ||
// If the tag has a name or property attribute, we use that as the key | ||
// to avoid duplicates and to ensure sorting of tags later | ||
const key = Object.entries(metaEntry.attrs ?? {}).find(([key]) => key === 'name' || key === 'property'); | ||
const headItemKey = `${metaEntry.tag}:${(0, util_1.isDefined)(key) ? (0, formula_1.applyFormula)(key[1], context) : (id ?? (0, nanoid_1.nanoid)())}`; | ||
const headItemKey = `${metaEntry.tag}:${isDefined(key) ? applyFormula(key[1], context) : (id ?? nanoid())}`; | ||
headItems.set(headItemKey, | ||
@@ -192,3 +191,3 @@ // Add the id to the tag so it's easier to dynamically update it later | ||
.map(([key, formula]) => { | ||
const value = (0, formula_1.applyFormula)(formula, context); | ||
const value = applyFormula(formula, context); | ||
if (value === true) { | ||
@@ -199,8 +198,8 @@ // If the value is true, we just return the key - this is useful | ||
} | ||
return `${key}="${(0, attributes_1.escapeAttrValue)(value)}"`; | ||
return `${key}="${escapeAttrValue(value)}"`; | ||
}) | ||
.join(' ')} ${const_1.VOID_HTML_ELEMENTS.includes(metaEntry.tag) | ||
.join(' ')} ${VOID_HTML_ELEMENTS.includes(metaEntry.tag) | ||
? `/>` | ||
: `>${metaEntry.content | ||
? (0, formula_1.applyFormula)(metaEntry.content, context) | ||
? applyFormula(metaEntry.content, context) | ||
: ''}</${metaEntry.tag}>`}`); | ||
@@ -212,4 +211,3 @@ } | ||
}; | ||
exports.getHeadItems = getHeadItems; | ||
const renderHeadItems = ({ headItems, ordering = exports.defaultHeadOrdering, }) => (0, collections_1.easySort)([...headItems.entries()], ([key]) => { | ||
export const renderHeadItems = ({ headItems, ordering = defaultHeadOrdering, }) => easySort([...headItems.entries()], ([key]) => { | ||
const index = ordering.indexOf(key); | ||
@@ -220,7 +218,6 @@ return index === -1 ? ordering.length : index; | ||
.join('\n '); | ||
exports.renderHeadItems = renderHeadItems; | ||
// It's difficult to find a "best practice" for ordering head tags, and it's unclear if it matters much | ||
// for crawlers/browsers. We're using a simple ordering that puts (what we believe is) the most relevant | ||
// tags first. | ||
exports.defaultHeadOrdering = [ | ||
export const defaultHeadOrdering = [ | ||
'meta:charset', | ||
@@ -245,3 +242,5 @@ 'meta:viewport', | ||
'meta:og:locale', | ||
// The stylesheets should be loaded asap to avoid any flickering | ||
'link:reset', | ||
'link:page', | ||
// Everything else comes after these predefined tags | ||
@@ -252,6 +251,6 @@ ]; | ||
const fallbackTitle = defaultTitle ?? component.name; | ||
if (!(0, util_1.isDefined)(pageInfo?.title)) { | ||
if (!isDefined(pageInfo?.title)) { | ||
return fallbackTitle; | ||
} | ||
const title = (0, formula_1.applyFormula)(pageInfo.title.formula, context); | ||
const title = applyFormula(pageInfo.title.formula, context); | ||
return typeof title === 'string' ? title : fallbackTitle; | ||
@@ -261,6 +260,6 @@ }; | ||
const pageInfo = component.route?.info; | ||
if (!(0, util_1.isDefined)(pageInfo?.description)) { | ||
if (!isDefined(pageInfo?.description)) { | ||
return defaultDescription; | ||
} | ||
const description = (0, formula_1.applyFormula)(pageInfo.description.formula, context); | ||
const description = applyFormula(pageInfo.description.formula, context); | ||
return typeof description === 'string' ? description : defaultDescription; | ||
@@ -267,0 +266,0 @@ }; |
@@ -1,19 +0,14 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getCharset = exports.getHtmlLanguage = void 0; | ||
const formula_1 = require("@toddledev/core/dist/formula/formula"); | ||
const getHtmlLanguage = ({ pageInfo, formulaContext, defaultLanguage = 'en', }) => { | ||
import { applyFormula } from '@toddledev/core/dist/formula/formula'; | ||
export const getHtmlLanguage = ({ pageInfo, formulaContext, defaultLanguage = 'en', }) => { | ||
const language = pageInfo?.language | ||
? (0, formula_1.applyFormula)(pageInfo.language.formula, formulaContext) | ||
? applyFormula(pageInfo.language.formula, formulaContext) | ||
: defaultLanguage; | ||
return typeof language === 'string' ? language : defaultLanguage; | ||
}; | ||
exports.getHtmlLanguage = getHtmlLanguage; | ||
const getCharset = ({ pageInfo, formulaContext, defaultCharset = 'utf-8', }) => { | ||
export const getCharset = ({ pageInfo, formulaContext, defaultCharset = 'utf-8', }) => { | ||
const charset = pageInfo?.charset | ||
? (0, formula_1.applyFormula)(pageInfo.charset.formula, formulaContext) | ||
? applyFormula(pageInfo.charset.formula, formulaContext) | ||
: defaultCharset; | ||
return typeof charset === 'string' ? charset : defaultCharset; | ||
}; | ||
exports.getCharset = getCharset; | ||
//# sourceMappingURL=html.js.map |
@@ -1,14 +0,7 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.escapeSearchParameters = exports.escapeSearchParameter = void 0; | ||
const util_1 = require("@toddledev/core/dist/utils/util"); | ||
const xss_1 = __importDefault(require("xss")); | ||
const escapeSearchParameter = (searchParameter) => typeof searchParameter === 'string' ? (0, xss_1.default)(searchParameter) : null; | ||
exports.escapeSearchParameter = escapeSearchParameter; | ||
const escapeSearchParameters = (searchParams) => new URLSearchParams([...searchParams.entries()].reduce((params, [key, value]) => { | ||
const escapedValue = (0, exports.escapeSearchParameter)(value); | ||
if ((0, util_1.isDefined)(escapedValue)) { | ||
import { isDefined } from '@toddledev/core/dist/utils/util'; | ||
import xss from 'xss'; | ||
export const escapeSearchParameter = (searchParameter) => typeof searchParameter === 'string' ? xss(searchParameter) : null; | ||
export const escapeSearchParameters = (searchParams) => new URLSearchParams([...searchParams.entries()].reduce((params, [key, value]) => { | ||
const escapedValue = escapeSearchParameter(value); | ||
if (isDefined(escapedValue)) { | ||
params[key] = escapedValue; | ||
@@ -18,3 +11,2 @@ } | ||
}, {})); | ||
exports.escapeSearchParameters = escapeSearchParameters; | ||
//# sourceMappingURL=request.js.map |
@@ -1,6 +0,3 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.defaultSpeculationRules = void 0; | ||
// See docs here https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/speculationrules | ||
exports.defaultSpeculationRules = { | ||
export const defaultSpeculationRules = { | ||
prerender: [ | ||
@@ -7,0 +4,0 @@ { |
@@ -1,9 +0,6 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.mapTemplateHeaders = exports.sanitizeProxyHeaders = exports.applyTemplateValues = void 0; | ||
const template_1 = require("@toddledev/core/dist/api/template"); | ||
const util_1 = require("@toddledev/core/dist/utils/util"); | ||
const headers_1 = require("../utils/headers"); | ||
const applyTemplateValues = (input, cookies) => { | ||
if (!(0, util_1.isDefined)(input)) { | ||
import { STRING_TEMPLATE } from '@toddledev/core/dist/api/template'; | ||
import { isDefined } from '@toddledev/core/dist/utils/util'; | ||
import { skipCookieHeader, skipToddleHeader } from '../utils/headers'; | ||
export const applyTemplateValues = (input, cookies) => { | ||
if (!isDefined(input)) { | ||
return ''; | ||
@@ -25,3 +22,3 @@ } | ||
if (cookieValue) { | ||
output = output.replaceAll((0, template_1.STRING_TEMPLATE)('cookies', cookieName), cookieValue); | ||
output = output.replaceAll(STRING_TEMPLATE('cookies', cookieName), cookieValue); | ||
} | ||
@@ -31,14 +28,11 @@ } | ||
}; | ||
exports.applyTemplateValues = applyTemplateValues; | ||
const sanitizeProxyHeaders = ({ cookies, headers, }) => new Headers((0, exports.mapTemplateHeaders)({ | ||
export const sanitizeProxyHeaders = ({ cookies, headers, }) => new Headers(mapTemplateHeaders({ | ||
cookies, | ||
headers: (0, headers_1.skipCookieHeader)((0, headers_1.skipToddleHeader)(headers)), | ||
headers: skipCookieHeader(skipToddleHeader(headers)), | ||
})); | ||
exports.sanitizeProxyHeaders = sanitizeProxyHeaders; | ||
const mapTemplateHeaders = ({ cookies, headers, }) => new Headers([...headers.entries()].map(([name, value]) => [ | ||
export const mapTemplateHeaders = ({ cookies, headers, }) => new Headers([...headers.entries()].map(([name, value]) => [ | ||
name, | ||
// Replace template values in the header value | ||
(0, exports.applyTemplateValues)(value, cookies), | ||
applyTemplateValues(value, cookies), | ||
])); | ||
exports.mapTemplateHeaders = mapTemplateHeaders; | ||
//# sourceMappingURL=template.js.map |
@@ -1,11 +0,8 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.removeTestData = removeTestData; | ||
const collections_1 = require("@toddledev/core/dist/utils/collections"); | ||
function removeTestData(component) { | ||
import { mapObject, omit } from '@toddledev/core/dist/utils/collections'; | ||
export function removeTestData(component) { | ||
return { | ||
...component, | ||
attributes: (0, collections_1.mapObject)(component.attributes, ([key, value]) => [ | ||
attributes: mapObject(component.attributes, ([key, value]) => [ | ||
key, | ||
(0, collections_1.omit)(value, ['testValue']), | ||
omit(value, ['testValue']), | ||
]), | ||
@@ -16,6 +13,6 @@ ...(component.route | ||
...component.route, | ||
path: component.route.path.map((p) => (0, collections_1.omit)(p, ['testValue'])), | ||
query: (0, collections_1.mapObject)(component.route.query, ([key, value]) => [ | ||
path: component.route.path.map((p) => omit(p, ['testValue'])), | ||
query: mapObject(component.route.query, ([key, value]) => [ | ||
key, | ||
(0, collections_1.omit)(value, ['testValue']), | ||
omit(value, ['testValue']), | ||
]), | ||
@@ -22,0 +19,0 @@ }, |
@@ -1,8 +0,5 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getPathSegments = exports.get404Page = exports.getRouteDestination = exports.matchRoutes = exports.matchRouteForUrl = exports.matchPageForUrl = void 0; | ||
const api_1 = require("@toddledev/core/dist/api/api"); | ||
const util_1 = require("@toddledev/core/dist/utils/util"); | ||
const formulaContext_1 = require("../rendering/formulaContext"); | ||
const matchPageForUrl = ({ url, components, }) => (0, exports.matchRoutes)({ | ||
import { getUrl } from '@toddledev/core/dist/api/api'; | ||
import { isDefined } from '@toddledev/core/dist/utils/util'; | ||
import { getParameters, getServerToddleObject, } from '../rendering/formulaContext'; | ||
export const matchPageForUrl = ({ url, components, }) => matchRoutes({ | ||
url, | ||
@@ -12,4 +9,3 @@ entries: getPages(components), | ||
}); | ||
exports.matchPageForUrl = matchPageForUrl; | ||
const matchRouteForUrl = ({ url, routes, }) => (0, exports.matchRoutes)({ | ||
export const matchRouteForUrl = ({ url, routes, }) => matchRoutes({ | ||
url, | ||
@@ -19,5 +15,4 @@ entries: Object.values(routes ?? {}), | ||
}); | ||
exports.matchRouteForUrl = matchRouteForUrl; | ||
const matchRoutes = ({ url, entries, getRoute, }) => { | ||
const pathSegments = (0, exports.getPathSegments)(url); | ||
export const matchRoutes = ({ url, entries, getRoute, }) => { | ||
const pathSegments = getPathSegments(url); | ||
const matches = Object.values(entries) | ||
@@ -53,11 +48,10 @@ .filter((entry) => { | ||
}; | ||
exports.matchRoutes = matchRoutes; | ||
const getRouteDestination = ({ files, req, route, }) => { | ||
export const getRouteDestination = ({ files, req, route, }) => { | ||
try { | ||
const requestUrl = new URL(req.url); | ||
const { searchParamsWithDefaults, pathParams } = (0, formulaContext_1.getParameters)({ | ||
const { searchParamsWithDefaults, pathParams } = getParameters({ | ||
route: route.source, | ||
req, | ||
}); | ||
const url = (0, api_1.getUrl)(route.destination, | ||
const url = getUrl(route.destination, | ||
// destination formulas should only have access to URL parameters from | ||
@@ -72,3 +66,3 @@ // the route's source definition + global formulas. | ||
}, | ||
toddle: (0, formulaContext_1.getServerToddleObject)(files), | ||
toddle: getServerToddleObject(files), | ||
}, | ||
@@ -93,7 +87,5 @@ // Redirects can redirect to relative URLs - rewrites can't | ||
}; | ||
exports.getRouteDestination = getRouteDestination; | ||
const get404Page = (components) => getPages(components).find((page) => page.name === '404'); | ||
exports.get404Page = get404Page; | ||
const getPages = (components) => Object.values(components).filter((c) => (0, util_1.isDefined)(c.route)); | ||
const getPathSegments = (url) => url.pathname | ||
export const get404Page = (components) => getPages(components).find((page) => page.name === '404'); | ||
const getPages = (components) => Object.values(components).filter((c) => isDefined(c.route)); | ||
export const getPathSegments = (url) => url.pathname | ||
.substring(1) | ||
@@ -103,3 +95,2 @@ .split('/') | ||
.map((s) => decodeURIComponent(s)); | ||
exports.getPathSegments = getPathSegments; | ||
//# sourceMappingURL=routing.js.map |
@@ -1,3 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
export {}; | ||
//# sourceMappingURL=ssr.types.js.map |
@@ -1,6 +0,3 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ToddleApiService = void 0; | ||
const formulaUtils_1 = require("@toddledev/core/dist/formula/formulaUtils"); | ||
class ToddleApiService { | ||
import { getFormulasInFormula } from '@toddledev/core/dist/formula/formulaUtils'; | ||
export class ToddleApiService { | ||
service; | ||
@@ -18,3 +15,3 @@ globalFormulas; | ||
const globalFormulas = this.globalFormulas; | ||
yield* (0, formulaUtils_1.getFormulasInFormula)({ | ||
yield* getFormulasInFormula({ | ||
formula: this.service.baseUrl, | ||
@@ -24,3 +21,3 @@ globalFormulas, | ||
}); | ||
yield* (0, formulaUtils_1.getFormulasInFormula)({ | ||
yield* getFormulasInFormula({ | ||
formula: this.service.docsUrl, | ||
@@ -30,3 +27,3 @@ globalFormulas, | ||
}); | ||
yield* (0, formulaUtils_1.getFormulasInFormula)({ | ||
yield* getFormulasInFormula({ | ||
formula: this.service.apiKey, | ||
@@ -37,3 +34,3 @@ globalFormulas, | ||
if (this.service.type === 'supabase') { | ||
yield* (0, formulaUtils_1.getFormulasInFormula)({ | ||
yield* getFormulasInFormula({ | ||
formula: this.service.meta?.projectUrl, | ||
@@ -61,3 +58,2 @@ globalFormulas, | ||
} | ||
exports.ToddleApiService = ToddleApiService; | ||
//# sourceMappingURL=ToddleApiService.js.map |
@@ -1,5 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.skipToddleHeader = exports.skipCookieHeader = void 0; | ||
const url_1 = require("@toddledev/core/dist/utils/url"); | ||
import { PROXY_URL_HEADER } from '@toddledev/core/dist/utils/url'; | ||
/** | ||
@@ -10,3 +7,3 @@ * Omit the `cookie` header from a set of headers. | ||
*/ | ||
const skipCookieHeader = (headers) => { | ||
export const skipCookieHeader = (headers) => { | ||
const newHeaders = new Headers(headers); | ||
@@ -16,3 +13,2 @@ newHeaders.delete('cookie'); | ||
}; | ||
exports.skipCookieHeader = skipCookieHeader; | ||
/** | ||
@@ -23,8 +19,7 @@ * Omit the x-toddle-url header from a set of headers. | ||
*/ | ||
const skipToddleHeader = (headers) => { | ||
export const skipToddleHeader = (headers) => { | ||
const newHeaders = new Headers(headers); | ||
newHeaders.delete(url_1.PROXY_URL_HEADER); | ||
newHeaders.delete(PROXY_URL_HEADER); | ||
return newHeaders; | ||
}; | ||
exports.skipToddleHeader = skipToddleHeader; | ||
//# sourceMappingURL=headers.js.map |
@@ -12,9 +12,4 @@ import type { Component } from '@toddledev/core/dist/component/component.types'; | ||
route?: import("@toddledev/core/dist/component/component.types").PageRoute | null; | ||
attributes: Record<string, { | ||
name: string; | ||
testValue: unknown; | ||
}>; | ||
variables: Record<string, { | ||
initialValue: import("@toddledev/core/dist/formula/formula").Formula; | ||
}>; | ||
attributes: Record<string, import("@toddledev/core/dist/component/component.types").ComponentAttribute>; | ||
variables: Record<string, import("@toddledev/core/dist/component/component.types").ComponentVariable>; | ||
formulas?: Record<string, import("@toddledev/core/dist/component/component.types").ComponentFormula>; | ||
@@ -21,0 +16,0 @@ contexts?: Record<string, import("@toddledev/core/dist/component/component.types").ComponentContext>; |
@@ -1,10 +0,6 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.transformRelativePaths = exports.isCloudflareImagePath = void 0; | ||
const isCloudflareImagePath = (path) => typeof path === 'string' && path.startsWith('/cdn-cgi/imagedelivery/'); | ||
exports.isCloudflareImagePath = isCloudflareImagePath; | ||
export const isCloudflareImagePath = (path) => typeof path === 'string' && path.startsWith('/cdn-cgi/imagedelivery/'); | ||
/** | ||
* Make all relative 'src' paths in a component absolute | ||
*/ | ||
const transformRelativePaths = (urlOrigin) => (component) => ({ | ||
export const transformRelativePaths = (urlOrigin) => (component) => ({ | ||
...component, | ||
@@ -38,3 +34,2 @@ nodes: Object.entries(component.nodes).reduce((acc, [key, node]) => { | ||
}); | ||
exports.transformRelativePaths = transformRelativePaths; | ||
//# sourceMappingURL=media.js.map |
@@ -1,5 +0,2 @@ | ||
"use strict"; | ||
// See https://github.com/ai/nanoid/blob/main/non-secure/index.js | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.nanoid = void 0; | ||
// This alphabet uses `A-Za-z0-9_-` symbols. | ||
@@ -12,3 +9,3 @@ // The order of characters is optimized for better gzip and brotli compression. | ||
const urlAlphabet = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; | ||
const nanoid = (size = 21) => { | ||
export const nanoid = (size = 21) => { | ||
let id = ''; | ||
@@ -23,3 +20,2 @@ // A compact alternative for `for (var i = 0; i < step; i++)`. | ||
}; | ||
exports.nanoid = nanoid; | ||
//# sourceMappingURL=nanoid.js.map |
@@ -12,9 +12,4 @@ import type { Component } from '@toddledev/core/dist/component/component.types'; | ||
route?: import("@toddledev/core/dist/component/component.types").PageRoute | null; | ||
attributes: Record<string, { | ||
name: string; | ||
testValue: unknown; | ||
}>; | ||
variables: Record<string, { | ||
initialValue: import("@toddledev/core/dist/formula/formula").Formula; | ||
}>; | ||
attributes: Record<string, import("@toddledev/core/dist/component/component.types").ComponentAttribute>; | ||
variables: Record<string, import("@toddledev/core/dist/component/component.types").ComponentVariable>; | ||
formulas?: Record<string, import("@toddledev/core/dist/component/component.types").ComponentFormula>; | ||
@@ -21,0 +16,0 @@ contexts?: Record<string, import("@toddledev/core/dist/component/component.types").ComponentContext>; |
@@ -1,4 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.replaceTagInNodes = void 0; | ||
/** | ||
@@ -8,3 +5,3 @@ * Used to replace any recursive references to the root component, as it would be rendered both by toddle runtime | ||
*/ | ||
const replaceTagInNodes = (oldTag, newTag) => (component) => ({ | ||
export const replaceTagInNodes = (oldTag, newTag) => (component) => ({ | ||
...component, | ||
@@ -27,3 +24,2 @@ nodes: Object.entries(component.nodes).reduce((acc, [key, node]) => { | ||
}); | ||
exports.replaceTagInNodes = replaceTagInNodes; | ||
//# sourceMappingURL=tags.js.map |
{ | ||
"name": "@toddledev/ssr", | ||
"license": "Apache-2.0", | ||
"type": "module", | ||
"homepage": "https://github.com/toddledev/toddle", | ||
@@ -15,7 +16,8 @@ "scripts": { | ||
"dependencies": { | ||
"@toddledev/core": "0.0.4", | ||
"@toddledev/core": "0.0.5-alpha.1", | ||
"@toddledev/std-lib": "0.0.5-alpha.1", | ||
"cookie": "1.0.2", | ||
"xss": "1.0.15" | ||
}, | ||
"version": "0.0.4" | ||
"version": "0.0.5-alpha.1" | ||
} |
@@ -29,4 +29,6 @@ import type { Component } from '@toddledev/core/dist/component/component.types' | ||
cssBasePath = '/.toddle/fonts/stylesheet/css2', | ||
page, | ||
resetStylesheetPath = '/_static/reset.css', | ||
pageStylesheetPath = `/.toddle/stylesheet/${page.name}.css`, | ||
files, | ||
page, | ||
project, | ||
@@ -42,2 +44,4 @@ theme, | ||
page: ToddleComponent<string> | ||
resetStylesheetPath?: string | ||
pageStylesheetPath?: string | ||
project: ToddleProject | ||
@@ -88,3 +92,2 @@ theme: OldTheme | Theme | ||
const stylesheetUrl = urlWithCacheBuster('/_static/reset.css', cacheBuster) | ||
const charset = getCharset({ pageInfo, formulaContext: context }) | ||
@@ -108,5 +111,8 @@ const descriptionItems: [HeadItemType, string][] = [] | ||
'link:reset', | ||
// The reset stylesheet should be loaded asap to avoid any flickering | ||
`<link rel="stylesheet" fetchpriority="high" href="${escapeAttrValue(stylesheetUrl)}" />`, | ||
`<link rel="stylesheet" fetchpriority="high" href="${escapeAttrValue(urlWithCacheBuster(resetStylesheetPath, cacheBuster))}" />`, | ||
], | ||
[ | ||
'link:page', | ||
`<link rel="stylesheet" fetchpriority="high" href="${escapeAttrValue(urlWithCacheBuster(pageStylesheetPath, cacheBuster))}" />`, | ||
], | ||
...preloadFonts, | ||
@@ -345,3 +351,5 @@ // Initialize default head items (meta + links) | ||
'meta:og:locale', | ||
// The stylesheets should be loaded asap to avoid any flickering | ||
'link:reset', | ||
'link:page', | ||
// Everything else comes after these predefined tags | ||
@@ -348,0 +356,0 @@ ] |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
104
4%Yes
NaN215920
-0.38%4
33.33%+ Added
+ Added
+ Added
- Removed