@stacksjs/sites 0.74.48 → 0.74.50
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/provision.js +1 -1
- package/dist/resolver.js +1 -1
- package/dist/scoping.js +1 -1
- package/package.json +7 -7
package/dist/provision.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{db}from"@stacksjs/database";export async function provisionSite(input){const existing=input.siteId?await db.selectFrom("sites").selectAll().where("id","=",input.siteId).executeTakeFirst():await db.selectFrom("sites").selectAll().where("subdomain","=",input.subdomain).executeTakeFirst(),settings=JSON.stringify(input.settings??{});let siteId,created=!1;if(existing){siteId=Number(existing.id);await db.updateTable("sites").set({settings,...input.timezone?{timezone:input.timezone}:{}}).where("id","=",siteId).execute()}else{const inserted=await db.insertInto("sites").values({name:input.name,subdomain:input.subdomain,status:"active",settings,...input.timezone?{timezone:input.timezone}:{}}).returning("id").executeTakeFirst();siteId=Number(inserted?.id);created=!0}const pagesCreated=[],pagesKept=[];if(input.pages?.length){const{createPageDocument,registerDefaultBlocks}=await import("@stacksjs/cms");registerDefaultBlocks();for(const page of input.pages){const path=page.slug==="/"?"/":`/${page.slug}`;if(await db.selectFrom("pages").select("id").where("site_id","=",siteId).where("path","=",path).executeTakeFirst()){pagesKept.push(path);continue}await createPageDocument(siteId,{title:page.title,slug:page.slug,status:page.status??"published",blocks:page.blocks??[],parentId:page.parentId});pagesCreated.push(path)}}return{siteId,subdomain:input.subdomain,created,pagesCreated,pagesKept}}
|
|
1
|
+
import{db}from"@stacksjs/database/runtime";export async function provisionSite(input){const existing=input.siteId?await db.selectFrom("sites").selectAll().where("id","=",input.siteId).executeTakeFirst():await db.selectFrom("sites").selectAll().where("subdomain","=",input.subdomain).executeTakeFirst(),settings=JSON.stringify(input.settings??{});let siteId,created=!1;if(existing){siteId=Number(existing.id);await db.updateTable("sites").set({settings,...input.timezone?{timezone:input.timezone}:{}}).where("id","=",siteId).execute()}else{const inserted=await db.insertInto("sites").values({name:input.name,subdomain:input.subdomain,status:"active",settings,...input.timezone?{timezone:input.timezone}:{}}).returning("id").executeTakeFirst();siteId=Number(inserted?.id);created=!0}const pagesCreated=[],pagesKept=[];if(input.pages?.length){const{createPageDocument,registerDefaultBlocks}=await import("@stacksjs/cms");registerDefaultBlocks();for(const page of input.pages){const path=page.slug==="/"?"/":`/${page.slug}`;if(await db.selectFrom("pages").select("id").where("site_id","=",siteId).where("path","=",path).executeTakeFirst()){pagesKept.push(path);continue}await createPageDocument(siteId,{title:page.title,slug:page.slug,status:page.status??"published",blocks:page.blocks??[],parentId:page.parentId});pagesCreated.push(path)}}return{siteId,subdomain:input.subdomain,created,pagesCreated,pagesKept}}
|
package/dist/resolver.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{config}from"@stacksjs/config";import{db}from"@stacksjs/database";export function normalizeHost(raw){if(!raw)return"";let host=raw.trim().toLowerCase();if(host.startsWith("[")){const close=host.indexOf("]");if(close!==-1)host=host.slice(0,close+1)}else{const colon=host.indexOf(":");if(colon!==-1)host=host.slice(0,colon)}return host.endsWith(".")?host.slice(0,-1):host}export function sitesOptions(){const raw=config.sites??{};return{enabled:raw.enabled??!1,baseDomain:normalizeHost(raw.baseDomain??""),platformHosts:(raw.platformHosts??[]).map(normalizeHost),strict:raw.strict??!1,trustProxyHost:raw.trustProxyHost??!0,cacheTtlSeconds:raw.cacheTtlSeconds??60}}export function classifyHost(host,options){if(!host||options.platformHosts.includes(host))return{kind:"platform"};const base=options.baseDomain;if(base&&host===base)return{kind:"platform"};if(base&&host.endsWith(`.${base}`)){const sub=host.slice(0,-(base.length+1));if(sub&&!sub.includes(".")&&sub!=="www")return{kind:"subdomain",subdomain:sub};return{kind:"platform"}}return{kind:"custom",domain:host}}export function requestHost(headers,options){const first=(options.trustProxyHost?headers.get("x-forwarded-host"):null)?.split(",")[0];return normalizeHost(first||headers.get("host"))}function rowToContext(row,host){let settings={};const rawSettings=row.settings;if(typeof rawSettings==="string"&&rawSettings)try{settings=JSON.parse(rawSettings)}catch{}else if(rawSettings&&typeof rawSettings==="object")settings=rawSettings;return{id:Number(row.id),uuid:String(row.uuid??""),name:String(row.name??""),subdomain:String(row.subdomain??""),host,teamId:row.team_id==null?null:Number(row.team_id),status:String(row.status??"active"),settings}}const SITE_COLUMNS=["id","uuid","name","subdomain","team_id","status","settings"];export const databaseSiteStore={async byDomain(domain){const link=await db.selectFrom("site_domains").where("domain","=",domain).where("verified_at","is not",null).select(["site_id"]).executeTakeFirst();if(!link)return null;const site=await db.selectFrom("sites").where("id","=",link.site_id).where("status","=","active").select([...SITE_COLUMNS]).executeTakeFirst();return site?rowToContext(site,domain):null},async bySubdomain(subdomain){const site=await db.selectFrom("sites").where("subdomain","=",subdomain).where("status","=","active").select([...SITE_COLUMNS]).executeTakeFirst();return site?rowToContext(site,`${subdomain}.${sitesOptions().baseDomain}`):null}};const CACHE_KEY=Symbol.for("stacks.sites.hostCache"),hostCache=globalThis[CACHE_KEY]??=new Map;export function clearSiteCache(){hostCache.clear()}export async function resolveSiteByHost(rawHost,store=databaseSiteStore,options=sitesOptions()){if(!options.enabled)return null;const host=normalizeHost(rawHost);if(!host)return null;const cached=hostCache.get(host);if(cached&&cached.expiresAt>Date.now())return cached.site;const kind=classifyHost(host,options);let site=null;if(kind.kind==="custom")site=await store.byDomain(kind.domain);else if(kind.kind==="subdomain")site=await store.bySubdomain(kind.subdomain);hostCache.set(host,{site,expiresAt:Date.now()+options.cacheTtlSeconds*1000});return site}export function isPlatformHost(rawHost,options=sitesOptions()){return classifyHost(normalizeHost(rawHost),options).kind==="platform"}
|
|
1
|
+
import{config}from"@stacksjs/config";import{db}from"@stacksjs/database/runtime";export function normalizeHost(raw){if(!raw)return"";let host=raw.trim().toLowerCase();if(host.startsWith("[")){const close=host.indexOf("]");if(close!==-1)host=host.slice(0,close+1)}else{const colon=host.indexOf(":");if(colon!==-1)host=host.slice(0,colon)}return host.endsWith(".")?host.slice(0,-1):host}export function sitesOptions(){const raw=config.sites??{};return{enabled:raw.enabled??!1,baseDomain:normalizeHost(raw.baseDomain??""),platformHosts:(raw.platformHosts??[]).map(normalizeHost),strict:raw.strict??!1,trustProxyHost:raw.trustProxyHost??!0,cacheTtlSeconds:raw.cacheTtlSeconds??60}}export function classifyHost(host,options){if(!host||options.platformHosts.includes(host))return{kind:"platform"};const base=options.baseDomain;if(base&&host===base)return{kind:"platform"};if(base&&host.endsWith(`.${base}`)){const sub=host.slice(0,-(base.length+1));if(sub&&!sub.includes(".")&&sub!=="www")return{kind:"subdomain",subdomain:sub};return{kind:"platform"}}return{kind:"custom",domain:host}}export function requestHost(headers,options){const first=(options.trustProxyHost?headers.get("x-forwarded-host"):null)?.split(",")[0];return normalizeHost(first||headers.get("host"))}function rowToContext(row,host){let settings={};const rawSettings=row.settings;if(typeof rawSettings==="string"&&rawSettings)try{settings=JSON.parse(rawSettings)}catch{}else if(rawSettings&&typeof rawSettings==="object")settings=rawSettings;return{id:Number(row.id),uuid:String(row.uuid??""),name:String(row.name??""),subdomain:String(row.subdomain??""),host,teamId:row.team_id==null?null:Number(row.team_id),status:String(row.status??"active"),settings}}const SITE_COLUMNS=["id","uuid","name","subdomain","team_id","status","settings"];export const databaseSiteStore={async byDomain(domain){const link=await db.selectFrom("site_domains").where("domain","=",domain).where("verified_at","is not",null).select(["site_id"]).executeTakeFirst();if(!link)return null;const site=await db.selectFrom("sites").where("id","=",link.site_id).where("status","=","active").select([...SITE_COLUMNS]).executeTakeFirst();return site?rowToContext(site,domain):null},async bySubdomain(subdomain){const site=await db.selectFrom("sites").where("subdomain","=",subdomain).where("status","=","active").select([...SITE_COLUMNS]).executeTakeFirst();return site?rowToContext(site,`${subdomain}.${sitesOptions().baseDomain}`):null}};const CACHE_KEY=Symbol.for("stacks.sites.hostCache"),hostCache=globalThis[CACHE_KEY]??=new Map;export function clearSiteCache(){hostCache.clear()}export async function resolveSiteByHost(rawHost,store=databaseSiteStore,options=sitesOptions()){if(!options.enabled)return null;const host=normalizeHost(rawHost);if(!host)return null;const cached=hostCache.get(host);if(cached&&cached.expiresAt>Date.now())return cached.site;const kind=classifyHost(host,options);let site=null;if(kind.kind==="custom")site=await store.byDomain(kind.domain);else if(kind.kind==="subdomain")site=await store.bySubdomain(kind.subdomain);hostCache.set(host,{site,expiresAt:Date.now()+options.cacheTtlSeconds*1000});return site}export function isPlatformHost(rawHost,options=sitesOptions()){return classifyHost(normalizeHost(rawHost),options).kind==="platform"}
|
package/dist/scoping.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveAuthenticatedTeamId}from"@stacksjs/auth";import{db}from"@stacksjs/database";import{currentSiteId}from"./context";import{SiteNotResolvedError}from"./context";export function forSite(qb,column="site_id",siteId=currentSiteId()){if(siteId==null)throw new SiteNotResolvedError("No site in request context");return qb.where(column,"=",siteId)}export function siteOwnership(){return{field:"site_id",resolve:async(_user,req)=>{const teamId=await resolveAuthenticatedTeamId(req??{});if(!teamId)return null;return(await db.selectFrom("sites").where("team_id","=",teamId).select(["id"]).execute()).map((row)=>Number(row.id))}}}
|
|
1
|
+
import{resolveAuthenticatedTeamId}from"@stacksjs/auth";import{db}from"@stacksjs/database/runtime";import{currentSiteId}from"./context";import{SiteNotResolvedError}from"./context";export function forSite(qb,column="site_id",siteId=currentSiteId()){if(siteId==null)throw new SiteNotResolvedError("No site in request context");return qb.where(column,"=",siteId)}export function siteOwnership(){return{field:"site_id",resolve:async(_user,req)=>{const teamId=await resolveAuthenticatedTeamId(req??{});if(!teamId)return null;return(await db.selectFrom("sites").where("team_id","=",teamId).select(["id"]).execute()).map((row)=>Number(row.id))}}}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacksjs/sites",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.74.
|
|
4
|
+
"version": "0.74.50",
|
|
5
5
|
"description": "The Stacks multi-site (request-level tenancy) functionality.",
|
|
6
6
|
"author": "Chris Breuer",
|
|
7
7
|
"contributors": [
|
|
@@ -56,18 +56,18 @@
|
|
|
56
56
|
"prepublishOnly": "bun run build"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@stacksjs/auth": "0.74.
|
|
60
|
-
"@stacksjs/config": "0.74.
|
|
61
|
-
"@stacksjs/database": "0.74.
|
|
62
|
-
"@stacksjs/router": "0.74.
|
|
59
|
+
"@stacksjs/auth": "0.74.50",
|
|
60
|
+
"@stacksjs/config": "0.74.50",
|
|
61
|
+
"@stacksjs/database": "0.74.50",
|
|
62
|
+
"@stacksjs/router": "0.74.50"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
|
-
"@stacksjs/error-handling": "0.74.
|
|
65
|
+
"@stacksjs/error-handling": "0.74.50",
|
|
66
66
|
"better-dx": "^0.2.24"
|
|
67
67
|
},
|
|
68
68
|
"sideEffects": false,
|
|
69
69
|
"peerDependencies": {
|
|
70
|
-
"@stacksjs/cms": "0.74.
|
|
70
|
+
"@stacksjs/cms": "0.74.50"
|
|
71
71
|
},
|
|
72
72
|
"peerDependenciesMeta": {
|
|
73
73
|
"@stacksjs/cms": {
|