@coreframe/scripts 0.1.9 → 0.1.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/assets.d.ts CHANGED
@@ -1,5 +1,3 @@
1
- import { Plugin } from "vite";
2
-
3
1
  //#region assets.d.ts
4
2
  type AssetManifest = Record<string, AssetManifestEntry>;
5
3
  type AssetManifestEntry = {
@@ -83,9 +81,9 @@ type CheckAssetsOptions = AssetWorkflowOptions & {
83
81
  type PublishAssetsOptions = AssetWorkflowOptions & {
84
82
  outputDir?: string;
85
83
  };
86
- type CoreframeAssetsPluginOptions = {
87
- devMaterialize?: boolean;
88
- cwd?: string;
84
+ type LoadedAssetManifest = {
85
+ manifest: AssetManifest;
86
+ problems: AssetProblem[];
89
87
  };
90
88
  declare function addAsset({
91
89
  alt,
@@ -109,10 +107,8 @@ declare function publishAssets({
109
107
  outputDir
110
108
  }?: PublishAssetsOptions): Promise<AssetPublishResult>;
111
109
  declare function materializeAsset(assetId: string, options?: BuildAssetsOptions): Promise<AssetBuildResult>;
112
- declare function coreframeAssetsPlugin({
113
- cwd,
114
- devMaterialize
115
- }?: CoreframeAssetsPluginOptions): Plugin;
116
110
  declare function printAssetResult(result: unknown, json?: boolean): void;
111
+ declare function readAssetManifest(cwd?: string): Promise<LoadedAssetManifest>;
112
+ declare function formatAssetProblems(problems: AssetProblem[]): string;
117
113
  //#endregion
118
- export { AddAssetOptions, AssetBuildEntry, AssetBuildResult, AssetManifest, AssetManifestEntry, AssetProblem, AssetPublishResult, AssetStatus, AssetStatusEntry, AssetVariant, AssetVariantStatus, AssetWorkflowOptions, BuildAssetsOptions, CheckAssetsOptions, CoreframeAssetsPluginOptions, PublishAssetsOptions, PublishedAsset, addAsset, buildAssets, checkAssets, coreframeAssetsPlugin, materializeAsset, printAssetResult, publishAssets };
114
+ export { AddAssetOptions, AssetBuildEntry, AssetBuildResult, AssetManifest, AssetManifestEntry, AssetProblem, AssetPublishResult, AssetStatus, AssetStatusEntry, AssetVariant, AssetVariantStatus, AssetWorkflowOptions, BuildAssetsOptions, CheckAssetsOptions, LoadedAssetManifest, PublishAssetsOptions, PublishedAsset, addAsset, buildAssets, checkAssets, formatAssetProblems, materializeAsset, printAssetResult, publishAssets, readAssetManifest };
package/dist/assets.js CHANGED
@@ -1,4 +1,3 @@
1
- import{createHash as e}from"node:crypto";import{copyFile as t,mkdir as n,readFile as r,stat as i,writeFile as a}from"node:fs/promises";import{dirname as o,extname as s,join as c,relative as l,resolve as u,sep as d}from"node:path";import f from"nano-spawn";const p=`assets-src`,m=c(`assets`,`manifest.json`),h=/^[a-z0-9]+(?:[/-][a-z0-9]+)*$/,g=/@asset\s+([a-z0-9][a-z0-9/-]*)/g,_=/^version https:\/\/git-lfs.github.com\/spec\/v1\n/m;async function v({alt:e,cwd:r=process.cwd(),file:i,id:a}){T(a);let s=k(a,i),c=u(r,s),l=u(r,i);await n(o(c),{recursive:!0}),await t(l,c),await N(r,s);let d=await E(r),f=await j(c);return d.manifest[a]={source:s,alt:e,width:f.width,height:f.height,variants:[]},await D(r,d.manifest),y({cwd:r,id:a,pull:!1})}async function y({cwd:e=process.cwd(),id:t,pull:n=!0,updateManifest:r=!0}={}){let{manifest:i,problems:a}=await E(e),o=[],s=[];for(let[r,c]of Object.entries(i)){if(t&&r!==t)continue;let l=u(e,c.source);if(!await z(l)){a.push(B(r,c.source));continue}if(await I(l)&&(n&&(await P(e,c.source),o.push(c.source)),await I(l))){a.push({code:`SOURCE_POINTER_MISSING_OBJECT`,message:`Source asset "${c.source}" is still a Git LFS pointer after a targeted pull.`,assetId:r,file:c.source,fix:`Run: git lfs pull --include="${c.source}"`});continue}let d=await A(e,r,c);i[r]={...c,variants:[d]},s.push({assetId:r,variants:[d]})}return t&&!i[t]&&a.push({code:`REFERENCE_MISSING`,message:`Asset "${t}" is not present in ${m}.`,assetId:t,fix:`Run: coreframe assets add <file> --id ${t} --alt "..."`}),r&&a.length===0&&s.length>0&&await D(e,i),{ok:a.length===0,assets:s,fetched:o,problems:a}}async function b({cwd:e=process.cwd(),fix:t=!1}={}){if(t){let t=await y({cwd:e}),n=await b({cwd:e,fix:!1});return{...n,ok:n.ok&&t.ok,problems:[...n.problems,...t.problems]}}let n=await E(e),r=[...n.problems],i=[],a=await L(e);for(let[a,o]of Object.entries(n.manifest)){h.test(a)||r.push({code:`INVALID_ASSET_ID`,message:`Asset ID "${a}" must use lowercase path segments.`,assetId:a}),o.alt.trim()||r.push({code:`INVALID_ALT`,message:`Asset "${a}" is missing alt text.`,assetId:a,file:o.source,fix:`Run: coreframe assets add ${o.source} --id ${a} --alt "..."`}),o.source.startsWith(`${p}/`)||r.push({code:`INVALID_SOURCE_PATH`,message:`Asset "${a}" source must be under ${p}/.`,assetId:a,file:o.source});let n=await z(u(e,o.source)),s=n?await F(e,o.source):!1;n?s||r.push({code:`LFS_NOT_TRACKED`,message:`Source asset "${o.source}" is not tracked by Git LFS.`,assetId:a,file:o.source,fix:`Run: git lfs track "${o.source}" && git add .gitattributes ${o.source}`}):r.push(B(a,o.source));let c=await Promise.all(o.variants.map(async t=>({...t,exists:await z(u(e,t.path))})));(o.variants.length===0||c.some(e=>!e.exists))&&r.push({code:`GENERATED_VARIANT_MISSING`,message:`Asset "${a}" is missing generated variants.`,assetId:a,file:o.source,fix:t?void 0:`Run: coreframe assets build --id ${a}`}),i.push({assetId:a,source:o.source,sourceExists:n,lfsTracked:s,variants:c})}for(let e of a)n.manifest[e.assetId]||r.push({code:`INVALID_REFERENCE`,message:`Asset reference "${e.assetId}" is not present in ${m}.`,assetId:e.assetId,file:e.file,fix:`Run: coreframe assets add <file> --id ${e.assetId} --alt "..."`});return{ok:r.length===0,assets:i,problems:r}}async function x({cwd:e=process.cwd(),env:r=process.env,outputDir:i}={}){let s=[...(await b({cwd:e})).problems],l=[],d=[],f=u(e,i??r.COREFRAME_ASSETS_PUBLISH_DIR??`release-upload/assets`),p=c(f,`asset-publish-report.json`);if(s.length===0){let{manifest:r}=await E(e);for(let[i,a]of Object.entries(r))for(let r of a.variants){let a=u(e,r.path),s=c(f,r.path),p={assetId:i,source:r.path,target:s,size:r.size};if(await z(s)){d.push(p);continue}await n(o(s),{recursive:!0}),await t(a,s),l.push(p)}}let m={ok:s.length===0,uploaded:l,skipped:d,reportPath:p,problems:s};return await n(o(p),{recursive:!0}),await a(p,`${JSON.stringify(m,null,2)}\n`),m}async function S(e,t={}){return y({...t,id:e})}function C({cwd:e=process.cwd(),devMaterialize:t=!0}={}){let n=`virtual:assets`,r=`\0${n}`;return{name:`coreframe:assets`,async buildStart(){if(this.meta.watchMode)return;let t=await b({cwd:e});if(!t.ok)throw Error(V(t.problems))},async resolveId(e){if(e===n)return r},async load(t){if(t!==r)return;let{manifest:n,problems:i}=await E(e);if(i.length>0)throw Error(V(i));return[`const manifest = ${JSON.stringify(n)};`,`export { manifest };`,`export function asset(id) {`,` const entry = manifest[id];`," if (!entry) throw new Error(`Unknown Coreframe asset: ${id}`);",` return entry;`,`}`].join(`
2
- `)},async transform(n,r){let i=[...n.matchAll(g)].map(e=>e[1]);if(i.length===0)return;let a=await E(e),o=[...a.problems],s=n;for(let n of i){let i=a.manifest[n];if(!i){o.push({code:`INVALID_REFERENCE`,message:`Asset reference "${n}" in "${r}" is not present in ${m}.`,assetId:n,file:r});continue}if(this.meta.watchMode&&t&&i.variants.length===0){this.warn(`Materializing Coreframe asset "${n}" for dev.`);let t=await S(n,{cwd:e,updateManifest:!1});o.push(...t.problems);let r=t.assets.find(e=>e.assetId===n);r&&(a.manifest[n]={...i,variants:r.variants})}let c=a.manifest[n]?.variants[0];if(!c){o.push({code:`GENERATED_VARIANT_MISSING`,message:`Asset "${n}" has no generated variant.`,assetId:n,file:r,fix:`Run: coreframe assets build --id ${n}`});continue}s=s.replaceAll(`@asset ${n}`,`/${c.path}`)}if(o.length>0)throw Error(V(o));return s}}}function w(e,t=!1){if(t){console.log(JSON.stringify(e,null,2));return}let n=e;n.problems&&n.problems.length>0&&console.error(V(n.problems)),console.log(n.ok===!1?`Asset workflow has problems.`:`Asset workflow complete.`)}function T(e){if(!h.test(e))throw Error(`Asset ID "${e}" must use lowercase path segments.`)}async function E(e){let t=u(e,m);if(!await z(t))return{manifest:{},problems:[{code:`MANIFEST_MISSING`,message:`${m} does not exist.`,file:m,fix:`Run: coreframe assets add <file> --id <asset-id> --alt "..."`}]};try{return{manifest:JSON.parse(await r(t,`utf8`)),problems:[]}}catch(e){return{manifest:{},problems:[{code:`INVALID_MANIFEST`,message:`${m} is not valid JSON: ${e.message}`,file:m}]}}}async function D(e,t){let r=u(e,m);await n(o(r),{recursive:!0}),await a(r,`${JSON.stringify(O(t),null,2)}\n`)}function O(e){return Object.fromEntries(Object.entries(e).sort(([e],[t])=>e.localeCompare(t)))}function k(e,t){return c(p,`${e}${s(t).toLowerCase()}`).split(d).join(`/`)}async function A(t,r,i){let s=await M(),l=u(t,i.source),d=Math.min(i.width,1200),f=c(`.coreframe/assets`,r),p=await s(l).resize({width:d,withoutEnlargement:!0}).webp().toBuffer(),m=e(`sha256`).update(p).digest(`hex`).slice(0,12),h=`${f}.${m}.${d}.webp`,g=u(t,h);await n(o(g),{recursive:!0}),await a(g,p);let _=await s(p).metadata();return{format:`webp`,width:_.width??d,height:_.height??Math.round(i.height/i.width*d),path:h,size:p.byteLength,hash:m}}async function j(e){let t=await(await M())(e).metadata();if(!t.width||!t.height)throw Error(`Could not read dimensions for ${e}.`);return{width:t.width,height:t.height}}async function M(){try{return(await import(`sharp`)).default}catch{throw Error(`The assets workflow requires the optional sharp dependency.`)}}async function N(e,t){await f(`git`,[`lfs`,`track`,t],{cwd:e})}async function P(e,t){await f(`git`,[`lfs`,`pull`,`--include=${t}`],{cwd:e})}async function F(e,t){try{return(await f(`git`,[`check-attr`,`filter`,`--`,t],{cwd:e})).stdout.includes(`filter: lfs`)}catch{return!1}}async function I(e){try{let t=await r(e,`utf8`);return _.test(t)}catch{return!1}}async function L(e){let t=await R(e),n=[];for(let i of t){let t=await r(u(e,i),`utf8`);for(let e of t.matchAll(g))n.push({assetId:e[1],file:i})}return n}async function R(e){return(await f(`git`,[`ls-files`,`*.md`,`*.mdx`,`*.ts`,`*.tsx`],{cwd:e})).stdout.split(/\r?\n/).map(e=>e.trim()).filter(Boolean).filter(e=>!e.startsWith(`dist/`))}async function z(e){try{return await i(e),!0}catch{return!1}}function B(e,t){return{code:`SOURCE_MISSING`,message:`Source asset "${t}" does not exist.`,assetId:e,file:t,fix:`Run: coreframe assets add <file> --id ${e} --alt "..."`}}function V(e){return e.map(e=>[`${e.code}: ${e.message}`,e.file?` file: ${l(process.cwd(),u(e.file))}`:void 0,e.fix?` fix: ${e.fix}`:void 0].filter(Boolean).join(`
1
+ import{createHash as e}from"node:crypto";import{copyFile as t,mkdir as n,readFile as r,stat as i,writeFile as a}from"node:fs/promises";import{dirname as o,extname as s,join as c,relative as l,resolve as u,sep as d}from"node:path";import f from"nano-spawn";const p=`assets-src`,m=c(`assets`,`manifest.json`),h=/^[a-z0-9]+(?:[/-][a-z0-9]+)*$/,g=/@asset\s+([a-z0-9][a-z0-9/-]*)/g,_=/^version https:\/\/git-lfs.github.com\/spec\/v1\n/m;async function v({alt:e,cwd:r=process.cwd(),file:i,id:a}){w(a);let s=O(a,i),c=u(r,s),l=u(r,i);await n(o(c),{recursive:!0}),await t(l,c),await M(r,s);let d=await T(r),f=await A(c);return d.manifest[a]={source:s,alt:e,width:f.width,height:f.height,variants:[]},await E(r,d.manifest),y({cwd:r,id:a,pull:!1})}async function y({cwd:e=process.cwd(),id:t,pull:n=!0,updateManifest:r=!0}={}){let{manifest:i,problems:a}=await T(e),o=[],s=[];for(let[r,c]of Object.entries(i)){if(t&&r!==t)continue;let l=u(e,c.source);if(!await R(l)){a.push(z(r,c.source));continue}if(await F(l)&&(n&&(await N(e,c.source),o.push(c.source)),await F(l))){a.push({code:`SOURCE_POINTER_MISSING_OBJECT`,message:`Source asset "${c.source}" is still a Git LFS pointer after a targeted pull.`,assetId:r,file:c.source,fix:`Run: git lfs pull --include="${c.source}"`});continue}let d=await k(e,r,c);i[r]={...c,variants:[d]},s.push({assetId:r,variants:[d]})}return t&&!i[t]&&a.push({code:`REFERENCE_MISSING`,message:`Asset "${t}" is not present in ${m}.`,assetId:t,fix:`Run: coreframe assets add <file> --id ${t} --alt "..."`}),r&&a.length===0&&s.length>0&&await E(e,i),{ok:a.length===0,assets:s,fetched:o,problems:a}}async function b({cwd:e=process.cwd(),fix:t=!1}={}){if(t){let t=await y({cwd:e}),n=await b({cwd:e,fix:!1});return{...n,ok:n.ok&&t.ok,problems:[...n.problems,...t.problems]}}let n=await T(e),r=[...n.problems],i=[],a=await I(e);for(let[a,o]of Object.entries(n.manifest)){h.test(a)||r.push({code:`INVALID_ASSET_ID`,message:`Asset ID "${a}" must use lowercase path segments.`,assetId:a}),o.alt.trim()||r.push({code:`INVALID_ALT`,message:`Asset "${a}" is missing alt text.`,assetId:a,file:o.source,fix:`Run: coreframe assets add ${o.source} --id ${a} --alt "..."`}),o.source.startsWith(`${p}/`)||r.push({code:`INVALID_SOURCE_PATH`,message:`Asset "${a}" source must be under ${p}/.`,assetId:a,file:o.source});let n=await R(u(e,o.source)),s=n?await P(e,o.source):!1;n?s||r.push({code:`LFS_NOT_TRACKED`,message:`Source asset "${o.source}" is not tracked by Git LFS.`,assetId:a,file:o.source,fix:`Run: git lfs track "${o.source}" && git add .gitattributes ${o.source}`}):r.push(z(a,o.source));let c=await Promise.all(o.variants.map(async t=>({...t,exists:await R(u(e,t.path))})));(o.variants.length===0||c.some(e=>!e.exists))&&r.push({code:`GENERATED_VARIANT_MISSING`,message:`Asset "${a}" is missing generated variants.`,assetId:a,file:o.source,fix:t?void 0:`Run: coreframe assets build --id ${a}`}),i.push({assetId:a,source:o.source,sourceExists:n,lfsTracked:s,variants:c})}for(let e of a)n.manifest[e.assetId]||r.push({code:`INVALID_REFERENCE`,message:`Asset reference "${e.assetId}" is not present in ${m}.`,assetId:e.assetId,file:e.file,fix:`Run: coreframe assets add <file> --id ${e.assetId} --alt "..."`});return{ok:r.length===0,assets:i,problems:r}}async function x({cwd:e=process.cwd(),env:r=process.env,outputDir:i}={}){let s=[...(await b({cwd:e})).problems],l=[],d=[],f=u(e,i??r.COREFRAME_ASSETS_PUBLISH_DIR??`release-upload/assets`),p=c(f,`asset-publish-report.json`);if(s.length===0){let{manifest:r}=await T(e);for(let[i,a]of Object.entries(r))for(let r of a.variants){let a=u(e,r.path),s=c(f,r.path),p={assetId:i,source:r.path,target:s,size:r.size};if(await R(s)){d.push(p);continue}await n(o(s),{recursive:!0}),await t(a,s),l.push(p)}}let m={ok:s.length===0,uploaded:l,skipped:d,reportPath:p,problems:s};return await n(o(p),{recursive:!0}),await a(p,`${JSON.stringify(m,null,2)}\n`),m}async function S(e,t={}){return y({...t,id:e})}function C(e,t=!1){if(t){console.log(JSON.stringify(e,null,2));return}let n=e;n.problems&&n.problems.length>0&&console.error(B(n.problems)),console.log(n.ok===!1?`Asset workflow has problems.`:`Asset workflow complete.`)}function w(e){if(!h.test(e))throw Error(`Asset ID "${e}" must use lowercase path segments.`)}async function T(e=process.cwd()){let t=u(e,m);if(!await R(t))return{manifest:{},problems:[{code:`MANIFEST_MISSING`,message:`${m} does not exist.`,file:m,fix:`Run: coreframe assets add <file> --id <asset-id> --alt "..."`}]};try{return{manifest:JSON.parse(await r(t,`utf8`)),problems:[]}}catch(e){return{manifest:{},problems:[{code:`INVALID_MANIFEST`,message:`${m} is not valid JSON: ${e.message}`,file:m}]}}}async function E(e,t){let r=u(e,m);await n(o(r),{recursive:!0}),await a(r,`${JSON.stringify(D(t),null,2)}\n`)}function D(e){return Object.fromEntries(Object.entries(e).sort(([e],[t])=>e.localeCompare(t)))}function O(e,t){return c(p,`${e}${s(t).toLowerCase()}`).split(d).join(`/`)}async function k(t,r,i){let s=await j(),l=u(t,i.source),d=Math.min(i.width,1200),f=c(`.coreframe/assets`,r),p=await s(l).resize({width:d,withoutEnlargement:!0}).webp().toBuffer(),m=e(`sha256`).update(p).digest(`hex`).slice(0,12),h=`${f}.${m}.${d}.webp`,g=u(t,h);await n(o(g),{recursive:!0}),await a(g,p);let _=await s(p).metadata();return{format:`webp`,width:_.width??d,height:_.height??Math.round(i.height/i.width*d),path:h,size:p.byteLength,hash:m}}async function A(e){let t=await(await j())(e).metadata();if(!t.width||!t.height)throw Error(`Could not read dimensions for ${e}.`);return{width:t.width,height:t.height}}async function j(){try{return(await import(`sharp`)).default}catch{throw Error(`The assets workflow requires the optional sharp dependency.`)}}async function M(e,t){await f(`git`,[`lfs`,`track`,t],{cwd:e})}async function N(e,t){await f(`git`,[`lfs`,`pull`,`--include=${t}`],{cwd:e})}async function P(e,t){try{return(await f(`git`,[`check-attr`,`filter`,`--`,t],{cwd:e})).stdout.includes(`filter: lfs`)}catch{return!1}}async function F(e){try{let t=await r(e,`utf8`);return _.test(t)}catch{return!1}}async function I(e){let t=await L(e),n=[];for(let i of t){let t=await r(u(e,i),`utf8`);for(let e of t.matchAll(g))n.push({assetId:e[1],file:i})}return n}async function L(e){return(await f(`git`,[`ls-files`,`*.md`,`*.mdx`,`*.ts`,`*.tsx`],{cwd:e})).stdout.split(/\r?\n/).map(e=>e.trim()).filter(Boolean).filter(e=>!e.startsWith(`dist/`))}async function R(e){try{return await i(e),!0}catch{return!1}}function z(e,t){return{code:`SOURCE_MISSING`,message:`Source asset "${t}" does not exist.`,assetId:e,file:t,fix:`Run: coreframe assets add <file> --id ${e} --alt "..."`}}function B(e){return e.map(e=>[`${e.code}: ${e.message}`,e.file?` file: ${l(process.cwd(),u(e.file))}`:void 0,e.fix?` fix: ${e.fix}`:void 0].filter(Boolean).join(`
3
2
  `)).join(`
4
- `)}export{v as addAsset,y as buildAssets,b as checkAssets,C as coreframeAssetsPlugin,S as materializeAsset,w as printAssetResult,x as publishAssets};
3
+ `)}export{v as addAsset,y as buildAssets,b as checkAssets,B as formatAssetProblems,S as materializeAsset,C as printAssetResult,x as publishAssets,T as readAssetManifest};
@@ -1,20 +1,10 @@
1
- import { startProjectPostgres } from "./local-postgres.js";
2
-
3
1
  //#region db/drizzle-kit.d.ts
4
- type Spawn = (file: string, args: readonly string[], options: {
5
- env: NodeJS.ProcessEnv;
6
- stdio: "inherit";
7
- }) => PromiseLike<unknown>;
8
2
  type DrizzleKitCommand = "generate" | "migrate" | "studio";
9
3
  type RunDrizzleKitCommandOptions = {
10
4
  env?: NodeJS.ProcessEnv;
11
- spawn?: Spawn;
12
- startProjectPostgres?: typeof startProjectPostgres;
13
5
  };
14
6
  declare function runDrizzleKitCommand(command: DrizzleKitCommand, args?: string[], {
15
- env,
16
- spawn,
17
- startProjectPostgres
7
+ env
18
8
  }?: RunDrizzleKitCommandOptions): Promise<void>;
19
9
  //#endregion
20
10
  export { runDrizzleKitCommand };
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{startProjectPostgres as e}from"./local-postgres.js";import t from"../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import n from"node:path";import r from"nano-spawn";import i from"node:process";const a=n.resolve(`node_modules`,`.bin`),o=i.platform===`win32`?`drizzle-kit.cmd`:`drizzle-kit`,s={startProjectPostgres:e};async function c(e,c=[],{env:l=i.env,spawn:u=r,startProjectPostgres:d=s.startProjectPostgres}={}){try{var f=t();let r=f.a(await d({env:l})),i=l.PATH??l.Path??``;await u(o,[e,...c],{env:{...r.env,PATH:a+n.delimiter+i},stdio:`inherit`})}catch(e){f.e=e}finally{await f.d()}}import.meta.main&&c(i.argv[2],i.argv.slice(3)).catch(e=>{console.error(e),i.exit(1)});export{c as runDrizzleKitCommand};
2
+ import{startProjectPostgres as e}from"./local-postgres.js";import t from"../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import n from"node:path";import r from"nano-spawn";import i from"node:process";const a=n.resolve(`node_modules`,`.bin`),o=i.platform===`win32`?`drizzle-kit.cmd`:`drizzle-kit`;async function s(s,c=[],{env:l=i.env}={}){try{var u=t();let i=u.a(await e({env:l})),d=l.PATH??l.Path??``;await r(o,[s,...c],{env:{...i.env,PATH:a+n.delimiter+d},stdio:`inherit`})}catch(e){u.e=e}finally{await u.d()}}import.meta.main&&s(i.argv[2],i.argv.slice(3)).catch(e=>{console.error(e),i.exit(1)});export{s as runDrizzleKitCommand};
@@ -1,27 +1,9 @@
1
- import { importProjectModule } from "../project.js";
2
- import { createLocalPostgresDb, startProjectPostgres } from "./local-postgres.js";
3
- import { planLocalSchemaPush } from "./schema-push.js";
4
- import { seedLocalDb } from "./seed.js";
5
- import { setupLocalDb } from "./setup.js";
6
-
7
1
  //#region db/ensure.d.ts
8
2
  type EnsureLocalDbOptions = {
9
- createLocalPostgresDb?: typeof createLocalPostgresDb;
10
3
  env?: NodeJS.ProcessEnv;
11
- importProjectModule?: typeof importProjectModule;
12
- planLocalSchemaPush?: typeof planLocalSchemaPush;
13
- seedLocalDb?: typeof seedLocalDb;
14
- startProjectPostgres?: typeof startProjectPostgres;
15
- setupLocalDb?: typeof setupLocalDb;
16
4
  };
17
5
  declare function ensureLocalDb({
18
- createLocalPostgresDb,
19
- env,
20
- importProjectModule,
21
- planLocalSchemaPush,
22
- seedLocalDb,
23
- startProjectPostgres,
24
- setupLocalDb
6
+ env
25
7
  }?: EnsureLocalDbOptions): Promise<void>;
26
8
  //#endregion
27
9
  export { ensureLocalDb };
package/dist/db/ensure.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{importProjectModule as e}from"../project.js";import{createLocalPostgresDb as t,startProjectPostgres as n}from"./local-postgres.js";import r from"../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{SEED_EMAILS as i,SEED_IDS as a}from"./config.js";import{inferSchemaDialect as o,planLocalSchemaPush as s}from"./schema-push.js";import{seedLocalDb as c}from"./seed.js";import{setupLocalDb as l}from"./setup.js";import{eq as u}from"drizzle-orm";const d={createLocalPostgresDb:t,importProjectModule:e,planLocalSchemaPush:s,seedLocalDb:c,startProjectPostgres:n,setupLocalDb:l};async function f(t=e){return{schema:await t(`src/db/schema.ts`)}}async function p(e,{users:t}){let[n]=await e.select({id:t.id}).from(t).where(u(t.email,i.adminUser)).limit(1);return n?.id===a.adminUser}async function m(e,{schema:t},n=s){let r=await n(o(t),t,e);return r.sqlStatements.length===0?(console.log(`Local database schema already in sync`),{appliedStatements:0,plan:r}):(console.log(`Local database schema drift detected; applying ${r.sqlStatements.length} statement(s)`),await r.apply(),console.log(`Local database schema synced`),{appliedStatements:r.sqlStatements.length,plan:r})}async function h({createLocalPostgresDb:e=d.createLocalPostgresDb,env:t=process.env,importProjectModule:n=d.importProjectModule,planLocalSchemaPush:i=d.planLocalSchemaPush,seedLocalDb:a=d.seedLocalDb,startProjectPostgres:o=d.startProjectPostgres,setupLocalDb:s=d.setupLocalDb}={}){try{var c=r();let l=c.a(await o({env:t})).env,u=await f(n),d=await e({env:l});try{if(await g(d,u.schema))console.log(`Local database already set up`);else{console.log(`Local database is missing or unseeded; running setup`),await s(`default`,{env:l});return}(await m(d,u,i)).appliedStatements>0&&!await g(d,u.schema)&&(console.log(`Local database seed data missing after schema sync; running seed`),await a(void 0,{env:l}))}finally{await d.$client.end()}}catch(e){c.e=e}finally{await c.d()}}async function g(e,t){try{return await p(e,t)}catch{return!1}}import.meta.main&&h().catch(e=>{console.error(e),process.exit(1)});export{h as ensureLocalDb};
2
+ import{importProjectModule as e}from"../project.js";import{createLocalPostgresDb as t,startProjectPostgres as n}from"./local-postgres.js";import r from"../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{SEED_EMAILS as i,SEED_IDS as a}from"./config.js";import{inferSchemaDialect as o,planLocalSchemaPush as s}from"./schema-push.js";import{seedLocalDb as c}from"./seed.js";import{setupLocalDb as l}from"./setup.js";import{eq as u}from"drizzle-orm";async function d(){return{schema:await e(`src/db/schema.ts`)}}async function f(e,{users:t}){let[n]=await e.select({id:t.id}).from(t).where(u(t.email,i.adminUser)).limit(1);return n?.id===a.adminUser}async function p(e,{schema:t}){let n=await s(o(t),t,e);return n.sqlStatements.length===0?(console.log(`Local database schema already in sync`),{appliedStatements:0,plan:n}):(console.log(`Local database schema drift detected; applying ${n.sqlStatements.length} statement(s)`),await n.apply(),console.log(`Local database schema synced`),{appliedStatements:n.sqlStatements.length,plan:n})}async function m({env:e=process.env}={}){try{var i=r();let a=i.a(await n({env:e})).env,o=await d(),s=await t({env:a});try{if(await h(s,o.schema))console.log(`Local database already set up`);else{console.log(`Local database is missing or unseeded; running setup`),await l(`default`,{env:a});return}(await p(s,o)).appliedStatements>0&&!await h(s,o.schema)&&(console.log(`Local database seed data missing after schema sync; running seed`),await c(void 0,{env:a}))}finally{await s.$client.end()}}catch(e){i.e=e}finally{await i.d()}}async function h(e,t){try{return await f(e,t)}catch{return!1}}import.meta.main&&m().catch(e=>{console.error(e),process.exit(1)});export{m as ensureLocalDb};
@@ -1,8 +1,6 @@
1
+ import { CoreframeConfig } from "../config.js";
1
2
  import { createProjectPostgresDrizzleDatabase } from "./project.js";
2
- import { CoreframeConfig, readProjectConfig } from "../config.js";
3
- import { readFile, rm } from "node:fs/promises";
4
- import { tmpdir } from "node:os";
5
- import { LocalPostgresEnv, PostgresOutputTarget, startPostgres } from "local-postgres";
3
+ import { LocalPostgresEnv, PostgresOutputTarget } from "local-postgres";
6
4
 
7
5
  //#region db/local-postgres.d.ts
8
6
  declare const LOCAL_POSTGRES_ENV_FLAG = "COREFRAME_LOCAL_POSTGRES";
@@ -31,37 +29,19 @@ type StartProjectPostgresOptions = {
31
29
  config?: CoreframeConfig;
32
30
  cwd?: string;
33
31
  env?: NodeJS.ProcessEnv;
34
- kill?: typeof process.kill;
35
32
  postgresOutput?: PostgresOutputTarget;
36
- readProjectConfig?: typeof readProjectConfig;
37
- readFile?: typeof readFile;
38
- rm?: typeof rm;
39
- startPostgres?: typeof startPostgres;
40
- };
41
- type StartTemporaryProjectPostgresOptions = StartProjectPostgresOptions & {
42
- mkdtemp?: (prefix: string) => Promise<string>;
43
- tmpdir?: typeof tmpdir;
44
33
  };
34
+ type StartTemporaryProjectPostgresOptions = StartProjectPostgresOptions;
45
35
  declare function startProjectPostgres({
46
36
  config,
47
37
  cwd,
48
38
  env,
49
- kill,
50
- postgresOutput,
51
- readProjectConfig,
52
- readFile,
53
- rm,
54
- startPostgres
39
+ postgresOutput
55
40
  }?: StartProjectPostgresOptions): Promise<ProjectPostgresSidecar>;
56
41
  declare function startTemporaryProjectPostgres({
57
42
  config,
58
43
  cwd,
59
- env,
60
- mkdtemp,
61
- readProjectConfig,
62
- rm,
63
- startPostgres,
64
- tmpdir
44
+ env
65
45
  }?: StartTemporaryProjectPostgresOptions): Promise<ProjectPostgresSidecar>;
66
46
  declare function createLocalPostgresEnv(env: NodeJS.ProcessEnv, postgresEnv: LocalPostgresEnv): NodeJS.ProcessEnv;
67
47
  declare function createLocalPostgresDb({
@@ -1,2 +1,2 @@
1
- import{readProjectConfig as e}from"../config.js";import{createProjectPostgresDrizzleDatabase as t}from"./project.js";import{mkdtemp as n,readFile as r,rm as i}from"node:fs/promises";import a from"node:path";import{tmpdir as o}from"node:os";import{startPostgres as s}from"local-postgres";const c=`COREFRAME_LOCAL_POSTGRES`,l=`coreframe`,u={name:`coreframe`,password:`coreframe`},d={kill:process.kill,mkdtemp:n,readFile:r,readProjectConfig:e,rm:i,startPostgres:s,tmpdir:o};async function f({config:e,cwd:t=process.cwd(),env:n=process.env,kill:r=d.kill,postgresOutput:i,readProjectConfig:o=d.readProjectConfig,readFile:s=d.readFile,rm:c=d.rm,startPostgres:f=d.startPostgres}={}){if(n.COREFRAME_LOCAL_POSTGRES===`1`||((e??await o({cwd:t})).database?.dialect??`postgres`)!==`postgres`)return _(n);let p=a.resolve(t,`.coreframe/postgres`),m=await v(p,s,r);if(m!==void 0)throw Error(`PostgreSQL is already running for this project (PID ${m}). Stop the other top-level \`coreframe dev\` process before starting another.`);let h=a.join(p,`postgres.log`);await c(h,{force:!0});let b;try{b=await f({dataDir:p,database:l,postgresOutput:i??{filePath:h},postgres:{strategy:`prefer-local`},superuser:u})}catch(e){throw await y(e,i?void 0:h,s)}return g(n,b)}async function p({config:e,cwd:t=process.cwd(),env:n=process.env,mkdtemp:r=d.mkdtemp,readProjectConfig:i=d.readProjectConfig,rm:o=d.rm,startPostgres:s=d.startPostgres,tmpdir:c=d.tmpdir}={}){let f=(e??await i({cwd:t})).database?.dialect??`postgres`;if(f!==`postgres`)throw Error(`Temporary schema push checks require PostgreSQL, but this project uses ${f}.`);let p=await r(a.join(c(),`coreframe-schema-check-`));try{let e=g(n,await s({dataDir:p,database:l,postgresOutput:`ignore`,postgres:{strategy:`prefer-local`},superuser:u}));return{env:e.env,async[Symbol.asyncDispose](){try{await e[Symbol.asyncDispose]()}finally{await o(p,{force:!0,recursive:!0})}}}}catch(e){throw await o(p,{force:!0,recursive:!0}),e}}function m(e,t){return{...e,...t,[c]:`1`}}async function h({env:e=process.env}={}){let n=x(e);return t({env:{...e,DATABASE_URL:n}})}function g(e,t){return{env:m(e,t.env),async[Symbol.asyncDispose](){await t[Symbol.asyncDispose]()}}}function _(e){return{env:e,async[Symbol.asyncDispose](){}}}async function v(e,t,n){let r;try{r=await t(a.join(e,`postmaster.pid`),`utf8`)}catch{return}let i=Number(r.split(`
2
- `,1)[0]);if(!(!Number.isSafeInteger(i)||i<=0))try{return n(i,0),i}catch(e){return b(e)&&e.code===`EPERM`?i:void 0}}async function y(e,t,n){let r=e instanceof Error?e.message:String(e),i;if(t)try{i=(await n(t,`utf8`)).trim()||void 0}catch{}let a=i?`\n\nPostgreSQL output:\n${i}`:``,o=t?`\n\nPostgreSQL log: ${t}`:``;return Error(`Local PostgreSQL failed to start: ${r}${a}${o}`,{cause:e})}function b(e){return e instanceof Error}function x(e=process.env){let t=e.DATABASE_URL||S(e);if(!t)throw Error(`DATABASE_URL or PGDATABASE, PGHOST, PGPORT, and PGUSER are required.`);return t}function S(e){let{PGDATABASE:t,PGHOST:n,PGPASSWORD:r,PGPORT:i,PGUSER:a}=e;if(!t||!n||!i||!a)return;let o=new URL(`postgresql://${n}:${i}/${t}`);return o.username=a,r&&(o.password=r),o.href}export{c as LOCAL_POSTGRES_ENV_FLAG,h as createLocalPostgresDb,m as createLocalPostgresEnv,x as getLocalPostgresConnectionString,f as startProjectPostgres,p as startTemporaryProjectPostgres};
1
+ import{readProjectConfig as e}from"../config.js";import{fs as t,os as n}from"../environment.js";import{createProjectPostgresDrizzleDatabase as r}from"./project.js";import i from"node:path";import{startPostgres as a}from"local-postgres";const o=`COREFRAME_LOCAL_POSTGRES`,s=`coreframe`,c={name:`coreframe`,password:`coreframe`};async function l({config:n,cwd:r=process.cwd(),env:o=process.env,postgresOutput:l}={}){if(o.COREFRAME_LOCAL_POSTGRES===`1`||((n??await e({cwd:r})).database?.dialect??`postgres`)!==`postgres`)return m(o);let u=i.resolve(r,`.coreframe/postgres`),d=await h(u);if(d!==void 0)throw Error(`PostgreSQL is already running for this project (PID ${d}). Stop the other top-level \`coreframe dev\` process before starting another.`);let f=i.join(u,`postgres.log`);await t.rm(f,{force:!0});let _;try{_=await a({dataDir:u,database:s,postgresOutput:l??{filePath:f},postgres:{strategy:`prefer-local`},superuser:c})}catch(e){throw await g(e,l?void 0:f)}return p(o,_)}async function u({config:r,cwd:o=process.cwd(),env:l=process.env}={}){let u=(r??await e({cwd:o})).database?.dialect??`postgres`;if(u!==`postgres`)throw Error(`Temporary schema push checks require PostgreSQL, but this project uses ${u}.`);let d=await t.mkdtemp(i.join(n.tmpdir(),`coreframe-schema-check-`));try{let e=p(l,await a({dataDir:d,database:s,postgresOutput:`ignore`,postgres:{strategy:`prefer-local`},superuser:c}));return{env:e.env,async[Symbol.asyncDispose](){try{await e[Symbol.asyncDispose]()}finally{await t.rm(d,{force:!0,recursive:!0})}}}}catch(e){throw await t.rm(d,{force:!0,recursive:!0}),e}}function d(e,t){return{...e,...t,[o]:`1`}}async function f({env:e=process.env}={}){let t=v(e);return r({env:{...e,DATABASE_URL:t}})}function p(e,t){return{env:d(e,t.env),async[Symbol.asyncDispose](){await t[Symbol.asyncDispose]()}}}function m(e){return{env:e,async[Symbol.asyncDispose](){}}}async function h(e){let r;try{r=await t.readFile(i.join(e,`postmaster.pid`),`utf8`)}catch{return}let a=Number(r.split(`
2
+ `,1)[0]);if(!(!Number.isSafeInteger(a)||a<=0))try{return n.kill(a,0),a}catch(e){return _(e)&&e.code===`EPERM`?a:void 0}}async function g(e,n){let r=e instanceof Error?e.message:String(e),i;if(n)try{i=(await t.readFile(n,`utf8`)).trim()||void 0}catch{}let a=i?`\n\nPostgreSQL output:\n${i}`:``,o=n?`\n\nPostgreSQL log: ${n}`:``;return Error(`Local PostgreSQL failed to start: ${r}${a}${o}`,{cause:e})}function _(e){return e instanceof Error}function v(e=process.env){let t=e.DATABASE_URL||y(e);if(!t)throw Error(`DATABASE_URL or PGDATABASE, PGHOST, PGPORT, and PGUSER are required.`);return t}function y(e){let{PGDATABASE:t,PGHOST:n,PGPASSWORD:r,PGPORT:i,PGUSER:a}=e;if(!t||!n||!i||!a)return;let o=new URL(`postgresql://${n}:${i}/${t}`);return o.username=a,r&&(o.password=r),o.href}export{o as LOCAL_POSTGRES_ENV_FLAG,f as createLocalPostgresDb,d as createLocalPostgresEnv,v as getLocalPostgresConnectionString,l as startProjectPostgres,u as startTemporaryProjectPostgres};
@@ -1,14 +1,12 @@
1
- import { DatabaseClient, DatabaseDialect } from "./client.js";
1
+ import { DatabaseDialect } from "./client.js";
2
2
 
3
3
  //#region db/migrate-held.d.ts
4
4
  type MigrateHeldOptions = {
5
5
  argv?: string[];
6
- database?: DatabaseClient;
7
6
  env?: NodeJS.ProcessEnv;
8
7
  };
9
8
  declare function migrateHeldMigrations({
10
9
  argv,
11
- database,
12
10
  env
13
11
  }?: MigrateHeldOptions): Promise<void>;
14
12
  declare function validateHeldMigrationHeader(sql: string, relativePath: string): void;
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{createProjectDeployDatabase as e}from"./project.js";import{collectHeldMigrationFiles as t,formatMigrationList as n}from"../deploy/migrations.js";import{createHash as r}from"node:crypto";import{readFile as i}from"node:fs/promises";const a=`--confirm=run-held-migrations`,o=[`-- Held migration:`,`-- Safe after:`,`-- Verification:`];async function s({argv:r=process.argv.slice(2),database:o,env:s=process.env}={}){let d=await t();if(console.log(`Held migration files:`),console.log(n(d)),!r.includes(a))throw Error(`Held migrations require explicit confirmation. Re-run with ${a}.`);if(d.length===0){console.log(`No held migrations to run.`);return}let m=o??await e({env:s});try{await u(m);for(let e of d){let t=await i(e.path,`utf8`);c(t,e.relativePath);let n=l(t),r=await m.execute(f(m.dialect,e.id));if(r.rows.length===1){if(r.rows[0]?.sha256!==n)throw Error(`Held migration ${e.relativePath} changed after it was applied.`);console.log(`Skipping already-applied held migration ${e.relativePath}`);continue}console.log(`Applying held migration ${e.relativePath}`),await h(m,async r=>{await r.execute(t),await r.execute(p(m.dialect,e.id,n))})}}finally{o||await m.close?.()}}function c(e,t){let n=o.filter(t=>!e.includes(t));if(n.length>0)throw Error(`${t} is missing held migration header fields: ${n.join(`, `)}`)}function l(e){return r(`sha256`).update(e).digest(`hex`)}async function u(e){for(let t of d(e.dialect))await e.execute(t)}function d(e){switch(e){case`postgres`:return[`create schema if not exists drizzle`,`create table if not exists drizzle.__held_migrations (
2
+ import{createProjectDeployDatabase as e}from"./project.js";import{collectHeldMigrationFiles as t,formatMigrationList as n}from"../deploy/migrations.js";import{createHash as r}from"node:crypto";import{readFile as i}from"node:fs/promises";const a=`--confirm=run-held-migrations`,o=[`-- Held migration:`,`-- Safe after:`,`-- Verification:`];async function s({argv:r=process.argv.slice(2),env:o=process.env}={}){let s=await t();if(console.log(`Held migration files:`),console.log(n(s)),!r.includes(a))throw Error(`Held migrations require explicit confirmation. Re-run with ${a}.`);if(s.length===0){console.log(`No held migrations to run.`);return}let d=await e({env:o});try{await u(d);for(let e of s){let t=await i(e.path,`utf8`);c(t,e.relativePath);let n=l(t),r=await d.execute(f(d.dialect,e.id));if(r.rows.length===1){if(r.rows[0]?.sha256!==n)throw Error(`Held migration ${e.relativePath} changed after it was applied.`);console.log(`Skipping already-applied held migration ${e.relativePath}`);continue}console.log(`Applying held migration ${e.relativePath}`),await h(d,async r=>{await r.execute(t),await r.execute(p(d.dialect,e.id,n))})}}finally{await d.close?.()}}function c(e,t){let n=o.filter(t=>!e.includes(t));if(n.length>0)throw Error(`${t} is missing held migration header fields: ${n.join(`, `)}`)}function l(e){return r(`sha256`).update(e).digest(`hex`)}async function u(e){for(let t of d(e.dialect))await e.execute(t)}function d(e){switch(e){case`postgres`:return[`create schema if not exists drizzle`,`create table if not exists drizzle.__held_migrations (
3
3
  id text primary key,
4
4
  sha256 text not null,
5
5
  applied_at timestamptz not null default now()
@@ -1,13 +1,9 @@
1
- import { startProjectPostgres } from "./local-postgres.js";
2
-
3
1
  //#region db/migrate.d.ts
4
2
  type MigrateLocalDbOptions = {
5
3
  env?: NodeJS.ProcessEnv;
6
- startProjectPostgres?: typeof startProjectPostgres;
7
4
  };
8
5
  declare function migrateLocalDb({
9
- env,
10
- startProjectPostgres
6
+ env
11
7
  }?: MigrateLocalDbOptions): Promise<void>;
12
8
  //#endregion
13
9
  export { migrateLocalDb };
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{createLocalPostgresDb as e,startProjectPostgres as t}from"./local-postgres.js";import n from"../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{MIGRATIONS_FOLDER as r}from"./config.js";import{access as i}from"node:fs/promises";import{resolve as a}from"node:path";import{migrate as o}from"drizzle-orm/node-postgres/migrator";const s=a(r),c={startProjectPostgres:t};async function l({env:t=process.env,startProjectPostgres:r=c.startProjectPostgres}={}){try{var a=n();await i(s);let c=await e({env:a.a(await r({env:t})).env});try{await o(c,{migrationsFolder:s}),console.log(`Applied local migrations from ${s}`)}finally{await c.$client.end()}}catch(e){a.e=e}finally{await a.d()}}import.meta.main&&l().catch(e=>{console.error(e),process.exit(1)});export{l as migrateLocalDb};
2
+ import{createLocalPostgresDb as e,startProjectPostgres as t}from"./local-postgres.js";import n from"../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{MIGRATIONS_FOLDER as r}from"./config.js";import{access as i}from"node:fs/promises";import{resolve as a}from"node:path";import{migrate as o}from"drizzle-orm/node-postgres/migrator";const s=a(r);async function c({env:r=process.env}={}){try{var a=n();await i(s);let c=await e({env:a.a(await t({env:r})).env});try{await o(c,{migrationsFolder:s}),console.log(`Applied local migrations from ${s}`)}finally{await c.$client.end()}}catch(e){a.e=e}finally{await a.d()}}import.meta.main&&c().catch(e=>{console.error(e),process.exit(1)});export{c as migrateLocalDb};
@@ -1,13 +1,10 @@
1
1
  import { DatabaseClient, DrizzleExecutor } from "./client.js";
2
- import { importProjectModule } from "../project.js";
3
2
  import { DatabaseConfig } from "../config.js";
4
3
 
5
4
  //#region db/project.d.ts
6
5
  type CreateProjectDatabaseOptions = {
7
6
  config?: DatabaseConfig;
8
7
  env?: NodeJS.ProcessEnv;
9
- importProjectDependency?: ImportProjectDependency;
10
- importProjectModule?: typeof importProjectModule;
11
8
  };
12
9
  type DrizzleDatabase = DrizzleExecutor & {
13
10
  $client?: {
@@ -15,17 +12,12 @@ type DrizzleDatabase = DrizzleExecutor & {
15
12
  end?(): Promise<void>;
16
13
  };
17
14
  };
18
- type ImportProjectDependency = <T>(specifier: string) => Promise<T>;
19
15
  declare function createProjectDeployDatabase({
20
16
  config,
21
- env,
22
- importProjectDependency,
23
- importProjectModule
17
+ env
24
18
  }?: CreateProjectDatabaseOptions): Promise<DatabaseClient>;
25
19
  declare function createProjectPostgresDrizzleDatabase({
26
- env,
27
- importProjectDependency,
28
- importProjectModule
20
+ env
29
21
  }?: CreateProjectDatabaseOptions): Promise<DrizzleDatabase>;
30
22
  //#endregion
31
23
  export { CreateProjectDatabaseOptions, createProjectDeployDatabase, createProjectPostgresDrizzleDatabase };
@@ -1 +1 @@
1
- import{readProjectConfig as e}from"../config.js";import{importProjectModule as t}from"../project.js";import{createDatabaseAdapter as n}from"./client.js";import{createRequire as r}from"node:module";import{resolve as i}from"node:path";import{pathToFileURL as a}from"node:url";const o=`src/db/relations.ts`,s={importProjectModule:t};async function c({config:t,env:n=process.env,importProjectDependency:r=f,importProjectModule:i=s.importProjectModule}={}){let a=(t??(await e()).database)?.dialect??`postgres`;if(a===`postgres`)return u({env:n,importProjectModule:i,importProjectDependency:r});if(a===`sqlite`)return d({env:n,importProjectModule:i,importProjectDependency:r});throw Error(`Unsupported database dialect "${a}".`)}async function l({env:e=process.env,importProjectDependency:t=f,importProjectModule:n=s.importProjectModule}={}){let r=e.DATABASE_URL;if(!r)throw Error(`DATABASE_URL is required to create the PostgreSQL database.`);let[{drizzle:i},{relations:a}]=await Promise.all([t(`drizzle-orm/node-postgres`),n(o)]);return i({connection:{connectionString:r,max:1},relations:a})}async function u({env:e,importProjectModule:t,importProjectDependency:r}){let i=await l({env:e,importProjectDependency:r,importProjectModule:t});return n({database:i,dialect:`postgres`,close:()=>i.$client?.end?.()??Promise.resolve()})}async function d({env:e,importProjectModule:t,importProjectDependency:r}){let i=e.TURSO_DATABASE_URL??e.DATABASE_URL;if(!i)throw Error(`TURSO_DATABASE_URL or DATABASE_URL is required to create the deploy database.`);let[{createClient:a},{drizzle:s},{relations:c}]=await Promise.all([r(`@libsql/client`),r(`drizzle-orm/libsql`),t(o)]),l=a({url:i,authToken:e.TURSO_AUTH_TOKEN});return n({database:s({client:l,relations:c}),dialect:`sqlite`,close:async()=>{await l.close?.()}})}async function f(e){return await import(a(r(i(`package.json`)).resolve(e)).href)}export{c as createProjectDeployDatabase,l as createProjectPostgresDrizzleDatabase};
1
+ import{readProjectConfig as e}from"../config.js";import{importProjectDependency as t,importProjectModule as n}from"../project.js";import{createDatabaseAdapter as r}from"./client.js";const i=`src/db/relations.ts`;async function a({config:t,env:n=process.env}={}){let r=(t??(await e()).database)?.dialect??`postgres`;if(r===`postgres`)return s({env:n});if(r===`sqlite`)return c({env:n});throw Error(`Unsupported database dialect "${r}".`)}async function o({env:e=process.env}={}){let r=e.DATABASE_URL;if(!r)throw Error(`DATABASE_URL is required to create the PostgreSQL database.`);let[{drizzle:a},{relations:o}]=await Promise.all([t(`drizzle-orm/node-postgres`),n(i)]);return a({connection:{connectionString:r,max:1},relations:o})}async function s({env:e}){let t=await o({env:e});return r({database:t,dialect:`postgres`,close:()=>t.$client?.end?.()??Promise.resolve()})}async function c({env:e}){let a=e.TURSO_DATABASE_URL??e.DATABASE_URL;if(!a)throw Error(`TURSO_DATABASE_URL or DATABASE_URL is required to create the deploy database.`);let[{createClient:o},{drizzle:s},{relations:c}]=await Promise.all([t(`@libsql/client`),t(`drizzle-orm/libsql`),n(i)]),l=o({url:a,authToken:e.TURSO_AUTH_TOKEN});return r({database:s({client:l,relations:c}),dialect:`sqlite`,close:async()=>{await l.close?.()}})}export{a as createProjectDeployDatabase,o as createProjectPostgresDrizzleDatabase};
@@ -1,13 +1,9 @@
1
- import { startProjectPostgres } from "./local-postgres.js";
2
-
3
1
  //#region db/reset.d.ts
4
2
  type ResetLocalDbOptions = {
5
3
  env?: NodeJS.ProcessEnv;
6
- startProjectPostgres?: typeof startProjectPostgres;
7
4
  };
8
5
  declare function resetLocalDb({
9
- env,
10
- startProjectPostgres
6
+ env
11
7
  }?: ResetLocalDbOptions): Promise<void>;
12
8
  //#endregion
13
9
  export { resetLocalDb };
package/dist/db/reset.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{createLocalPostgresDb as e,startProjectPostgres as t}from"./local-postgres.js";import n from"../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{sql as r}from"drizzle-orm";const i={startProjectPostgres:t};async function a({env:t=process.env,startProjectPostgres:a=i.startProjectPostgres}={}){try{var o=n();let i=await e({env:o.a(await a({env:t})).env});try{await i.execute(r`drop schema if exists public cascade`),await i.execute(r`create schema public`),console.log(`Reset local PostgreSQL schema`)}finally{await i.$client.end()}}catch(e){o.e=e}finally{await o.d()}}import.meta.main&&a().catch(e=>{console.error(e),process.exit(1)});export{a as resetLocalDb};
2
+ import{createLocalPostgresDb as e,startProjectPostgres as t}from"./local-postgres.js";import n from"../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{sql as r}from"drizzle-orm";async function i({env:i=process.env}={}){try{var a=n();let o=await e({env:a.a(await t({env:i})).env});try{await o.execute(r`drop schema if exists public cascade`),await o.execute(r`create schema public`),console.log(`Reset local PostgreSQL schema`)}finally{await o.$client.end()}}catch(e){a.e=e}finally{await a.d()}}import.meta.main&&i().catch(e=>{console.error(e),process.exit(1)});export{i as resetLocalDb};
@@ -1,26 +1,11 @@
1
- import { importProjectModule } from "../project.js";
2
- import { createLocalPostgresDb, startTemporaryProjectPostgres } from "./local-postgres.js";
3
- import { planLocalSchemaPush } from "./schema-push.js";
4
- import { runProjectSeed } from "./seed.js";
5
-
6
1
  //#region db/schema-check.d.ts
7
2
  type CheckSchemaPushOptions = {
8
- createLocalPostgresDb?: typeof createLocalPostgresDb;
9
3
  env?: NodeJS.ProcessEnv;
10
- importProjectModule?: typeof importProjectModule;
11
- planLocalSchemaPush?: typeof planLocalSchemaPush;
12
4
  seed?: boolean;
13
- runProjectSeed?: typeof runProjectSeed;
14
- startTemporaryProjectPostgres?: typeof startTemporaryProjectPostgres;
15
5
  };
16
6
  declare function checkSchemaPush({
17
- createLocalPostgresDb,
18
7
  env,
19
- importProjectModule,
20
- planLocalSchemaPush,
21
- seed,
22
- runProjectSeed,
23
- startTemporaryProjectPostgres
8
+ seed
24
9
  }?: CheckSchemaPushOptions): Promise<void>;
25
10
  //#endregion
26
11
  export { checkSchemaPush };
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{importProjectModule as e}from"../project.js";import{createLocalPostgresDb as t,startTemporaryProjectPostgres as n}from"./local-postgres.js";import r from"../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{inferSchemaDialect as i,planLocalSchemaPush as a}from"./schema-push.js";import{runProjectSeed as o}from"./seed.js";const s={createLocalPostgresDb:t,importProjectModule:e,planLocalSchemaPush:a,runProjectSeed:o,startTemporaryProjectPostgres:n};async function c({createLocalPostgresDb:e=s.createLocalPostgresDb,env:t=process.env,importProjectModule:n=s.importProjectModule,planLocalSchemaPush:a=s.planLocalSchemaPush,seed:o=!1,runProjectSeed:c=s.runProjectSeed,startTemporaryProjectPostgres:u=s.startTemporaryProjectPostgres}={}){try{var d=r();console.log(`Checking Drizzle schema against a throwaway PostgreSQL database`);let s=d.a(await u({env:t})),f=await n(`src/db/schema.ts`),p=await e({env:s.env});try{let e=i(f);if(e!==`postgres`)throw Error(`Temporary schema push checks require PostgreSQL schema, but found ${e}.`);let t=await a(e,f,p);t.sqlStatements.length===0?console.log(`Drizzle schema check passed with no changes`):(console.log(`Applying ${t.sqlStatements.length} statement(s) to throwaway database`),await t.apply(),console.log(`Drizzle schema check passed`)),o&&(console.log(`Seeding throwaway database`),await c(`default`,{env:s.env}),console.log(`Throwaway database seed check passed`))}finally{await l(p)}}catch(e){d.e=e}finally{await d.d()}}function l(e){return e.$client.end()}import.meta.main&&c().catch(e=>{console.error(e),process.exit(1)});export{c as checkSchemaPush};
2
+ import{importProjectModule as e}from"../project.js";import{createLocalPostgresDb as t,startTemporaryProjectPostgres as n}from"./local-postgres.js";import r from"../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{inferSchemaDialect as i,planLocalSchemaPush as a}from"./schema-push.js";import{runProjectSeed as o}from"./seed.js";async function s({env:s=process.env,seed:l=!1}={}){try{var u=r();console.log(`Checking Drizzle schema against a throwaway PostgreSQL database`);let d=u.a(await n({env:s})),f=await e(`src/db/schema.ts`),p=await t({env:d.env});try{let e=i(f);if(e!==`postgres`)throw Error(`Temporary schema push checks require PostgreSQL schema, but found ${e}.`);let t=await a(e,f,p);t.sqlStatements.length===0?console.log(`Drizzle schema check passed with no changes`):(console.log(`Applying ${t.sqlStatements.length} statement(s) to throwaway database`),await t.apply(),console.log(`Drizzle schema check passed`)),l&&(console.log(`Seeding throwaway database`),await o(`default`,{env:d.env}),console.log(`Throwaway database seed check passed`))}finally{await c(p)}}catch(e){u.e=e}finally{await u.d()}}function c(e){return e.$client.end()}import.meta.main&&s().catch(e=>{console.error(e),process.exit(1)});export{s as checkSchemaPush};
package/dist/db/seed.d.ts CHANGED
@@ -1,31 +1,18 @@
1
- import { importProjectModule } from "../project.js";
2
- import { startProjectPostgres } from "./local-postgres.js";
3
- import { readProjectConfig } from "../config.js";
4
1
  import { SeedProfile } from "./config.js";
5
2
 
6
3
  //#region db/seed.d.ts
7
4
  type SeedLocalDbOptions = {
8
5
  env?: NodeJS.ProcessEnv;
9
- importProjectModule?: typeof importProjectModule;
10
- readProjectConfig?: typeof readProjectConfig;
11
- startProjectPostgres?: typeof startProjectPostgres;
12
6
  };
13
7
  type RunProjectSeedOptions = {
14
8
  env: NodeJS.ProcessEnv;
15
- importProjectModule?: typeof importProjectModule;
16
- readProjectConfig?: typeof readProjectConfig;
17
9
  seedEntryPoint?: string;
18
10
  };
19
11
  declare function seedLocalDb(profile?: SeedProfile, {
20
- env,
21
- importProjectModule,
22
- readProjectConfig,
23
- startProjectPostgres
12
+ env
24
13
  }?: SeedLocalDbOptions): Promise<void>;
25
14
  declare function runProjectSeed(profile: SeedProfile | undefined, {
26
15
  env,
27
- importProjectModule,
28
- readProjectConfig,
29
16
  seedEntryPoint
30
17
  }: RunProjectSeedOptions): Promise<void>;
31
18
  //#endregion
package/dist/db/seed.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{readProjectConfig as e}from"../config.js";import{importProjectModule as t}from"../project.js";import{startProjectPostgres as n}from"./local-postgres.js";import r from"../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{getSeedProfile as i}from"./config.js";const a={importProjectModule:t,readProjectConfig:e,startProjectPostgres:n};async function o(e=i(),{env:t=process.env,importProjectModule:n=a.importProjectModule,readProjectConfig:o=a.readProjectConfig,startProjectPostgres:l=a.startProjectPostgres}={}){try{var u=r();let i=await o(),a=c(i);await s(e,{env:u.a(await l({config:i,env:t})).env,importProjectModule:n,readProjectConfig:o,seedEntryPoint:a}),console.log(`Seeded local database with "${e}" profile`)}catch(e){u.e=e}finally{await u.d()}}async function s(e=i(),{env:t,importProjectModule:n=a.importProjectModule,readProjectConfig:r=a.readProjectConfig,seedEntryPoint:o}){o??=c(await r()),await u(t,async()=>{await l(await n(o),o)({env:t,profile:e})})}function c(e){let t=e.database?.seed;if(!t)throw Error(`coreframe.config.ts must configure database.seed before running db seed.`);return t}function l(e,t){let n=e.default??e.seed??e.seedLocalDb;if(!n)throw Error(`${t} must export a default seed function, seed function, or seedLocalDb function.`);return n}async function u(e,t){let n=new Map;for(let[t,r]of Object.entries(e))n.set(t,process.env[t]),r===void 0?delete process.env[t]:process.env[t]=r;try{await t()}finally{for(let[e,t]of n)t===void 0?delete process.env[e]:process.env[e]=t}}import.meta.main&&o().catch(e=>{console.error(e),process.exit(1)});export{s as runProjectSeed,o as seedLocalDb};
2
+ import{readProjectConfig as e}from"../config.js";import{importProjectModule as t}from"../project.js";import{startProjectPostgres as n}from"./local-postgres.js";import r from"../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{getSeedProfile as i}from"./config.js";async function a(t=i(),{env:a=process.env}={}){try{var c=r();let i=await e(),l=s(i);await o(t,{env:c.a(await n({config:i,env:a})).env,seedEntryPoint:l}),console.log(`Seeded local database with "${t}" profile`)}catch(e){c.e=e}finally{await c.d()}}async function o(n=i(),{env:r,seedEntryPoint:a}){a??=s(await e()),await l(r,async()=>{await c(await t(a),a)({env:r,profile:n})})}function s(e){let t=e.database?.seed;if(!t)throw Error(`coreframe.config.ts must configure database.seed before running db seed.`);return t}function c(e,t){let n=e.default??e.seed??e.seedLocalDb;if(!n)throw Error(`${t} must export a default seed function, seed function, or seedLocalDb function.`);return n}async function l(e,t){let n=new Map;for(let[t,r]of Object.entries(e))n.set(t,process.env[t]),r===void 0?delete process.env[t]:process.env[t]=r;try{await t()}finally{for(let[e,t]of n)t===void 0?delete process.env[e]:process.env[e]=t}}import.meta.main&&a().catch(e=>{console.error(e),process.exit(1)});export{o as runProjectSeed,a as seedLocalDb};
@@ -1,14 +1,11 @@
1
- import { startProjectPostgres } from "./local-postgres.js";
2
1
  import { SeedProfile } from "./config.js";
3
2
 
4
3
  //#region db/setup.d.ts
5
4
  type SetupLocalDbOptions = {
6
5
  env?: NodeJS.ProcessEnv;
7
- startProjectPostgres?: typeof startProjectPostgres;
8
6
  };
9
7
  declare function setupLocalDb(profile?: SeedProfile, {
10
- env,
11
- startProjectPostgres
8
+ env
12
9
  }?: SetupLocalDbOptions): Promise<void>;
13
10
  //#endregion
14
11
  export { setupLocalDb };
package/dist/db/setup.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{startProjectPostgres as e}from"./local-postgres.js";import t from"../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{seedLocalDb as n}from"./seed.js";import{migrateLocalDb as r}from"./migrate.js";import{resetLocalDb as i}from"./reset.js";const a={startProjectPostgres:e};async function o(e=`default`,{env:o=process.env,startProjectPostgres:s=a.startProjectPostgres}={}){try{var c=t();let a=c.a(await s({env:o})).env;await i({env:a}),await r({env:a}),await n(e,{env:a})}catch(e){c.e=e}finally{await c.d()}}import.meta.main&&o().catch(e=>{console.error(e),process.exit(1)});export{o as setupLocalDb};
2
+ import{startProjectPostgres as e}from"./local-postgres.js";import t from"../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{seedLocalDb as n}from"./seed.js";import{migrateLocalDb as r}from"./migrate.js";import{resetLocalDb as i}from"./reset.js";async function a(a=`default`,{env:o=process.env}={}){try{var s=t();let c=s.a(await e({env:o})).env;await i({env:c}),await r({env:c}),await n(a,{env:c})}catch(e){s.e=e}finally{await s.d()}}import.meta.main&&a().catch(e=>{console.error(e),process.exit(1)});export{a as setupLocalDb};
@@ -1,4 +1,3 @@
1
- import nanoSpawn from "nano-spawn";
2
1
  import { UserConfig } from "vite";
3
2
 
4
3
  //#region dev-https.d.ts
@@ -6,11 +5,9 @@ declare const devHttpsCertEnv = "COREFRAME_HTTPS_CERT";
6
5
  declare const devHttpsKeyEnv = "COREFRAME_HTTPS_KEY";
7
6
  type PrepareDevHttpsOptions = {
8
7
  cwd?: string;
9
- spawn?: typeof nanoSpawn;
10
8
  };
11
9
  declare function prepareDevHttps({
12
- cwd,
13
- spawn
10
+ cwd
14
11
  }?: PrepareDevHttpsOptions): Promise<{
15
12
  cert: string;
16
13
  key: string;
package/dist/dev-https.js CHANGED
@@ -1 +1 @@
1
- import{access as e,chmod as t,mkdir as n}from"node:fs/promises";import r from"node:path";import i from"nano-spawn";import{readFileSync as a}from"node:fs";const o=`COREFRAME_HTTPS_CERT`,s=`COREFRAME_HTTPS_KEY`;async function c({cwd:a=process.cwd(),spawn:o=i}={}){let s=r.resolve(a,`.coreframe`,`https`),c=r.join(s,`localhost.pem`),l=r.join(s,`localhost-key.pem`);if(!await u(c,l)){let i;try{i=(await o(`mkcert`,[`-CAROOT`],{stdin:`ignore`})).stdout.trim()}catch{throw Error("Local HTTPS requires mkcert. Install it, run `mkcert -install`, then retry `coreframe dev --https`.")}try{await e(r.join(i,`rootCA.pem`))}catch{throw Error("The mkcert local CA is not initialized. Run `mkcert -install`, then retry `coreframe dev --https`.")}await n(s,{recursive:!0}),await o(`mkcert`,[`-cert-file`,c,`-key-file`,l,`localhost`,`127.0.0.1`,`::1`],{stdin:`ignore`}),process.platform!==`win32`&&await t(l,384)}return{cert:c,key:l}}function l(e=process.env){let t=e[o],n=e[s];if(!t&&!n)return{};if(!t||!n)throw Error(`${o} and ${s} must be set together.`);return{server:{https:{cert:a(t),key:a(n)}}}}async function u(...t){try{return await Promise.all(t.map(t=>e(t))),!0}catch{return!1}}export{l as coreframeDevHttpsConfig,o as devHttpsCertEnv,s as devHttpsKeyEnv,c as prepareDevHttps};
1
+ import{fs as e}from"./environment.js";import t from"node:path";import n from"nano-spawn";const r=`COREFRAME_HTTPS_CERT`,i=`COREFRAME_HTTPS_KEY`;async function a({cwd:r=process.cwd()}={}){let i=t.resolve(r,`.coreframe`,`https`),a=t.join(i,`localhost.pem`),o=t.join(i,`localhost-key.pem`);if(!await s(a,o)){let r;try{r=(await n(`mkcert`,[`-CAROOT`],{stdin:`ignore`})).stdout.trim()}catch{throw Error("Local HTTPS requires mkcert. Install it, run `mkcert -install`, then retry `coreframe dev --https`.")}try{await e.access(t.join(r,`rootCA.pem`))}catch{throw Error("The mkcert local CA is not initialized. Run `mkcert -install`, then retry `coreframe dev --https`.")}await e.mkdir(i,{recursive:!0}),await n(`mkcert`,[`-cert-file`,a,`-key-file`,o,`localhost`,`127.0.0.1`,`::1`],{stdin:`ignore`}),process.platform!==`win32`&&await e.chmod(o,384)}return{cert:a,key:o}}function o(t=process.env){let n=t[r],a=t[i];if(!n&&!a)return{};if(!n||!a)throw Error(`${r} and ${i} must be set together.`);return{server:{https:{cert:e.readFileSync(n),key:e.readFileSync(a)}}}}async function s(...t){try{return await Promise.all(t.map(t=>e.access(t))),!0}catch{return!1}}export{o as coreframeDevHttpsConfig,r as devHttpsCertEnv,i as devHttpsKeyEnv,a as prepareDevHttps};
package/dist/dev.d.ts CHANGED
@@ -1,17 +1,11 @@
1
- import { startProjectPostgres } from "./db/local-postgres.js";
2
- import { prepareDevHttps } from "./dev-https.js";
3
- import { CoreframeConfig, readProjectConfig } from "./config.js";
1
+ import { CoreframeConfig } from "./config.js";
4
2
 
5
3
  //#region dev.d.ts
6
4
  type DevServerOptions = {
7
5
  cwd?: string;
8
6
  env?: NodeJS.ProcessEnv;
9
- getAvailablePort?: typeof getAvailablePort;
10
7
  https?: boolean;
11
8
  platform?: DevPlatform;
12
- prepareDevHttps?: typeof prepareDevHttps;
13
- readProjectConfig?: typeof readProjectConfig;
14
- startProjectPostgres?: typeof startProjectPostgres;
15
9
  webPort?: number;
16
10
  };
17
11
  declare const devPlatforms: readonly ["web", "desktop", "ios", "android"];
@@ -20,14 +14,9 @@ declare function resolveDevPlatforms(config: CoreframeConfig): DevPlatform[];
20
14
  declare function runDevServer({
21
15
  cwd,
22
16
  env,
23
- getAvailablePort,
24
17
  https,
25
18
  platform,
26
- prepareDevHttps,
27
- readProjectConfig,
28
- startProjectPostgres,
29
19
  webPort
30
20
  }?: DevServerOptions): Promise<void>;
31
- declare function getAvailablePort(): Promise<number>;
32
21
  //#endregion
33
22
  export { DevPlatform, DevServerOptions, devPlatforms, resolveDevPlatforms, runDevServer };
package/dist/dev.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{readProjectConfig as e}from"./config.js";import{startProjectPostgres as t}from"./db/local-postgres.js";import n from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{devHttpsCertEnv as r,devHttpsKeyEnv as i,prepareDevHttps as a}from"./dev-https.js";import{mkdir as o}from"node:fs/promises";import s from"node:path";import c from"node:process";import{createServer as l}from"node:net";import{PassThrough as u}from"node:stream";import{supervise as d}from"procband";const f=[`web`,`desktop`,`ios`,`android`];function p(e){let t=e.dev?.platforms??[`web`];for(let e of t)if(!f.includes(e))throw Error(`Invalid development platform "${String(e)}". Expected one of: ${f.join(`, `)}.`);return[...new Set(t)]}const m=s.resolve(`node_modules`,`.bin`),h=c.platform===`win32`?`pnpm.cmd`:`pnpm`,g=c.platform===`win32`?`react-router.cmd`:`react-router`,_=c.platform===`win32`?`turso.cmd`:`turso`,v={getAvailablePort:x,prepareDevHttps:a,readProjectConfig:e,startProjectPostgres:t};async function y({cwd:e=c.cwd(),env:t=c.env,getAvailablePort:a=v.getAvailablePort,https:l=!1,platform:f=`web`,prepareDevHttps:p=v.prepareDevHttps,readProjectConfig:y=v.readProjectConfig,startProjectPostgres:x=v.startProjectPostgres,webPort:T}={}){let E=t.PATH??t.Path??``,D=f===`web`?T??w(t.COREFRAME_WEB_PORT):void 0,O,k=t;if(l&&f!==`web`)throw Error(`Local HTTPS is only supported for the web development platform.`);try{if(f===`web`){let f=await y({cwd:e}),v=l?await p({cwd:e}):void 0;if(k=v?{...t,[r]:v.cert,[i]:v.key}:t,f.database?.dialect===`sqlite`){let n=await a(),r=s.resolve(e,`.coreframe`),i=s.join(r,`turso.db`);await o(r,{recursive:!0}),k={...k,TURSO_DATABASE_URL:`http://127.0.0.1:${n}`},O=d({name:`turso`,command:_,args:[`dev`,`--port`,String(n),`--db-file`,i],cwd:e,env:t}),await O.waitFor(`listening`),await d({name:`db`,command:h,args:[`db`,`ensure`],cwd:e,env:k,prefix:!1}).expectSuccess()}if(b(f)){let t=new u,r=d({name:`postgres`,command:c.execPath,args:[`-e`,`process.stdin.pipe(process.stdout)`],cwd:e,stdin:t});try{try{var A=n();let r=A.a(await x({config:f,cwd:e,env:k,postgresOutput:t})).env;await d({name:`db`,command:h,args:[`db`,`ensure`],cwd:e,env:r,prefix:!1}).expectSuccess(),await d({name:`web`,command:g,args:C(D),cwd:e,env:{...r,CLOUDFLARE_ENV:`development`,PATH:m+s.delimiter+E}}).expectSuccess()}catch(e){A.e=e}finally{await A.d()}}finally{t.end(),await r.expectSuccess()}return}await d({name:`web`,command:g,args:C(D),cwd:e,env:{...k,CLOUDFLARE_ENV:`development`,PATH:m+s.delimiter+E}}).expectSuccess();return}let v=S(f);await d({name:f,command:h,args:v,cwd:e,env:t}).expectSuccess()}finally{O&&O.kill(`SIGTERM`)}}function b(e){return(e.database?.dialect??`postgres`)===`postgres`}async function x(){let e=l();try{await new Promise((t,n)=>{e.once(`error`,n),e.listen(0,`127.0.0.1`,t)});let t=e.address();if(!t||typeof t==`string`)throw Error(`Could not allocate a port for Turso dev.`);return t.port}finally{e.listening&&await new Promise((t,n)=>{e.close(e=>e?n(e):t())})}}function S(e){return[`--dir=tauri`,`tauri`,...e===`desktop`?[]:[e],`dev`]}function C(e){return e===void 0?[`dev`]:[`dev`,`--port`,String(e)]}function w(e){if(e===void 0)return;let t=Number(e);if(!Number.isInteger(t)||t<=0||t>65535)throw Error(`COREFRAME_WEB_PORT must be a valid TCP port.`);return t}import.meta.main&&y({env:{...c.env,FORCE_COLOR:`1`}}).catch(e=>{console.error(e),c.exit(1)});export{f as devPlatforms,p as resolveDevPlatforms,y as runDevServer};
2
+ import{readProjectConfig as e}from"./config.js";import{fs as t,net as n}from"./environment.js";import{startProjectPostgres as r}from"./db/local-postgres.js";import i from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{devHttpsCertEnv as a,devHttpsKeyEnv as o,prepareDevHttps as s}from"./dev-https.js";import c from"node:path";import l from"node:process";import{PassThrough as u}from"node:stream";import{supervise as d}from"procband";const f=[`web`,`desktop`,`ios`,`android`];function p(e){let t=e.dev?.platforms??[`web`];for(let e of t)if(!f.includes(e))throw Error(`Invalid development platform "${String(e)}". Expected one of: ${f.join(`, `)}.`);return[...new Set(t)]}const m=c.resolve(`node_modules`,`.bin`),h=l.platform===`win32`?`pnpm.cmd`:`pnpm`,g=l.platform===`win32`?`react-router.cmd`:`react-router`,_=l.platform===`win32`?`turso.cmd`:`turso`;async function v({cwd:f=l.cwd(),env:p=l.env,https:v=!1,platform:C=`web`,webPort:w}={}){let T=p.PATH??p.Path??``,E=C===`web`?w??S(p.COREFRAME_WEB_PORT):void 0,D,O=p;if(v&&C!==`web`)throw Error(`Local HTTPS is only supported for the web development platform.`);try{if(C===`web`){let b=await e({cwd:f}),S=v?await s({cwd:f}):void 0;if(O=S?{...p,[a]:S.cert,[o]:S.key}:p,b.database?.dialect===`sqlite`){let e=await n.getAvailablePort(),r=c.resolve(f,`.coreframe`),i=c.join(r,`turso.db`);await t.mkdir(r,{recursive:!0}),O={...O,TURSO_DATABASE_URL:`http://127.0.0.1:${e}`},D=d({name:`turso`,command:_,args:[`dev`,`--port`,String(e),`--db-file`,i],cwd:f,env:p}),await D.waitFor(`listening`),await d({name:`db`,command:h,args:[`db`,`ensure`],cwd:f,env:O,prefix:!1}).expectSuccess()}if(y(b)){let e=new u,t=d({name:`postgres`,command:l.execPath,args:[`-e`,`process.stdin.pipe(process.stdout)`],cwd:f,stdin:e});try{try{var k=i();let t=k.a(await r({config:b,cwd:f,env:O,postgresOutput:e})).env;await d({name:`db`,command:h,args:[`db`,`ensure`],cwd:f,env:t,prefix:!1}).expectSuccess(),await d({name:`web`,command:g,args:x(E),cwd:f,env:{...t,CLOUDFLARE_ENV:`development`,PATH:m+c.delimiter+T}}).expectSuccess()}catch(e){k.e=e}finally{await k.d()}}finally{e.end(),await t.expectSuccess()}return}await d({name:`web`,command:g,args:x(E),cwd:f,env:{...O,CLOUDFLARE_ENV:`development`,PATH:m+c.delimiter+T}}).expectSuccess();return}let S=b(C);await d({name:C,command:h,args:S,cwd:f,env:p}).expectSuccess()}finally{D&&D.kill(`SIGTERM`)}}function y(e){return(e.database?.dialect??`postgres`)===`postgres`}function b(e){return[`--dir=tauri`,`tauri`,...e===`desktop`?[]:[e],`dev`]}function x(e){return e===void 0?[`dev`]:[`dev`,`--port`,String(e)]}function S(e){if(e===void 0)return;let t=Number(e);if(!Number.isInteger(t)||t<=0||t>65535)throw Error(`COREFRAME_WEB_PORT must be a valid TCP port.`);return t}import.meta.main&&v({env:{...l.env,FORCE_COLOR:`1`}}).catch(e=>{console.error(e),l.exit(1)});export{f as devPlatforms,p as resolveDevPlatforms,v as runDevServer};
@@ -0,0 +1,24 @@
1
+ import { access, chmod, mkdir, mkdtemp, readFile, rm } from "node:fs/promises";
2
+ import { readFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+
5
+ //#region environment.d.ts
6
+ declare const fs: {
7
+ access: typeof access;
8
+ chmod: typeof chmod;
9
+ mkdir: typeof mkdir;
10
+ mkdtemp: typeof mkdtemp;
11
+ readFile: typeof readFile;
12
+ readFileSync: typeof readFileSync;
13
+ rm: typeof rm;
14
+ };
15
+ declare const net: {
16
+ getAvailablePort: typeof getAvailablePort;
17
+ };
18
+ declare const os: {
19
+ kill: (pid: number, signal?: string | number) => true;
20
+ tmpdir: typeof tmpdir;
21
+ };
22
+ declare function getAvailablePort(): Promise<number>;
23
+ //#endregion
24
+ export { fs, net, os };
@@ -0,0 +1 @@
1
+ import{access as e,chmod as t,mkdir as n,mkdtemp as r,readFile as i,rm as a}from"node:fs/promises";import o from"node:process";import{readFileSync as s}from"node:fs";import{createServer as c}from"node:net";import{tmpdir as l}from"node:os";const u={access:e,chmod:t,mkdir:n,mkdtemp:r,readFile:i,readFileSync:s,rm:a},d={getAvailablePort:p},f={kill:o.kill,tmpdir:l};async function p(){let e=c();try{await new Promise((t,n)=>{e.once(`error`,n),e.listen(0,`127.0.0.1`,t)});let t=e.address();if(!t||typeof t==`string`)throw Error(`Could not allocate an available TCP port.`);return t.port}finally{e.listening&&await new Promise((t,n)=>{e.close(e=>e?n(e):t())})}}export{u as fs,d as net,f as os};
package/dist/project.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  //#region project.d.ts
2
2
  declare function importProjectModule<T>(path: string): Promise<T>;
3
+ declare function importProjectDependency<T>(specifier: string): Promise<T>;
3
4
  //#endregion
4
- export { importProjectModule };
5
+ export { importProjectDependency, importProjectModule };
package/dist/project.js CHANGED
@@ -1 +1 @@
1
- import{resolve as e}from"node:path";import{pathToFileURL as t}from"node:url";async function n(n){return await import(t(e(process.cwd(),n)).href)}export{n as importProjectModule};
1
+ import{createRequire as e}from"node:module";import{resolve as t}from"node:path";import{pathToFileURL as n}from"node:url";async function r(e){return await import(n(t(process.cwd(),e)).href)}async function i(r){return await import(n(e(t(`package.json`)).resolve(r)).href)}export{i as importProjectDependency,r as importProjectModule};
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{coreframeGitRef as e,coreframeTemplateFile as t}from"./template-ref.js";import{join as n}from"node:path";import{tmpdir as r}from"node:os";import{existsSync as i,mkdtempSync as a,readFileSync as o,rmSync as s,writeFileSync as c}from"node:fs";import{spawnSync as l}from"node:child_process";const u=`.agents/skills/coreframe-upgrade/SKILL.md`;function d(e,t={}){return l(`git`,e,t)}function f(e){return e.stderr.toString(`utf8`).trim()||e.stdout.toString(`utf8`).trim()}function p(e,n){let r=t(e,n),i=d([`show`,r],{encoding:`utf8`});if(i.status!==0){let e=f(i);throw Error(`Could not read ${r}.${e?` ${e}`:``}`)}return i.stdout.toString()}function m(){let e=d([`rev-parse`,`--show-toplevel`],{encoding:`utf8`});if(e.status!==0){let t=f(e);throw Error(`Could not find git repository root.${t?` ${t}`:``}`)}return e.stdout.toString().trim()}function h(e,t){let i=a(n(r(),`coreframe-upgrade-skill-`)),o=n(i,`SKILL.md`);try{c(o,t);let n=f(d([`--no-pager`,`diff`,`--no-index`,`--color=never`,`--`,e,o]));n&&console.log(n)}finally{s(i,{force:!0,recursive:!0})}}function g({apply:t,target:r}){let a=n(m(),u),s=e(r);if(!i(a))throw Error(`Local ${u} does not exist.`);let l=o(a,`utf8`),d=p(r,u);return l===d?(console.log(`Coreframe upgrade skill matches ${s}:template/${u}.`),0):t?(c(a,d),console.error(`Updated ${u} from ${s}:template. Reread it before continuing the upgrade.`),20):(console.error(`Coreframe upgrade skill differs from ${s}:template/${u}.`),console.error(`Run again with --apply to update it, then reread ${u} before continuing.`),h(a,d),20)}if(import.meta.main){let e=process.argv.indexOf(`--target`),t=e===-1?null:process.argv[e+1];t||(console.error(`Usage: coreframe upgrade check-skill-current --target <git-ref> [--apply]`),process.exit(64));try{process.exit(g({apply:process.argv.includes(`--apply`),target:t}))}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exit(65)}}export{g as checkUpgradeSkillCurrent};
2
+ import{coreframeGitRef as e,coreframeTemplateFile as t}from"./template-ref.js";import{join as n}from"node:path";import{existsSync as r,mkdtempSync as i,readFileSync as a,rmSync as o,writeFileSync as s}from"node:fs";import{tmpdir as c}from"node:os";import{spawnSync as l}from"node:child_process";const u=`.agents/skills/coreframe-upgrade/SKILL.md`;function d(e,t={}){return l(`git`,e,t)}function f(e){return e.stderr.toString(`utf8`).trim()||e.stdout.toString(`utf8`).trim()}function p(e,n){let r=t(e,n),i=d([`show`,r],{encoding:`utf8`});if(i.status!==0){let e=f(i);throw Error(`Could not read ${r}.${e?` ${e}`:``}`)}return i.stdout.toString()}function m(){let e=d([`rev-parse`,`--show-toplevel`],{encoding:`utf8`});if(e.status!==0){let t=f(e);throw Error(`Could not find git repository root.${t?` ${t}`:``}`)}return e.stdout.toString().trim()}function h(e,t){let r=i(n(c(),`coreframe-upgrade-skill-`)),a=n(r,`SKILL.md`);try{s(a,t);let n=f(d([`--no-pager`,`diff`,`--no-index`,`--color=never`,`--`,e,a]));n&&console.log(n)}finally{o(r,{force:!0,recursive:!0})}}function g({apply:t,target:i}){let o=n(m(),u),c=e(i);if(!r(o))throw Error(`Local ${u} does not exist.`);let l=a(o,`utf8`),d=p(i,u);return l===d?(console.log(`Coreframe upgrade skill matches ${c}:template/${u}.`),0):t?(s(o,d),console.error(`Updated ${u} from ${c}:template. Reread it before continuing the upgrade.`),20):(console.error(`Coreframe upgrade skill differs from ${c}:template/${u}.`),console.error(`Run again with --apply to update it, then reread ${u} before continuing.`),h(o,d),20)}if(import.meta.main){let e=process.argv.indexOf(`--target`),t=e===-1?null:process.argv[e+1];t||(console.error(`Usage: coreframe upgrade check-skill-current --target <git-ref> [--apply]`),process.exit(64));try{process.exit(g({apply:process.argv.includes(`--apply`),target:t}))}catch(e){console.error(e instanceof Error?e.message:String(e)),process.exit(65)}}export{g as checkUpgradeSkillCurrent};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coreframe/scripts",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/airlock-labs/coreframe.git",
@@ -1,18 +0,0 @@
1
- import { ConfigEnv, FSWatcher } from "vite";
2
-
3
- //#region image-generator.d.ts
4
- declare function imageGenerator(): {
5
- name: string;
6
- configResolved(config: {
7
- command: ConfigEnv["command"];
8
- }): void;
9
- configureServer(server: {
10
- watcher: FSWatcher;
11
- }): Promise<void>;
12
- applyToEnvironment(environment: {
13
- name: string;
14
- }): boolean;
15
- buildStart(): Promise<void>;
16
- };
17
- //#endregion
18
- export { imageGenerator };
@@ -1 +0,0 @@
1
- import e from"node:path";import t from"node:fs";import{glob as n}from"tinyglobby";function r(){let e;return{name:`image-generator`,configResolved(t){e=t.command},async configureServer(e){await i(),e.watcher.on(`add`,e=>{a(e)&&o(e)}),e.watcher.on(`change`,e=>{a(e)&&o(e,{overwrite:!0})})},applyToEnvironment(e){return e.name===`client`},async buildStart(){e===`build`&&await i()}}}async function i(){let e=await n([`src/**/*@3x.{png,webp}`,`public/**/*@3x.{png,webp}`]);console.log(`[image-generator] Found ${e.length} @3x images.`),await Promise.all(e.map(e=>o(e)))}function a(e){return/@3x\.(png|webp)$/.test(e)}async function o(n,r={}){let i=e.dirname(n),a=e.extname(n),o=e.basename(n,`@3x${a}`),c=[{outputPath:e.join(i,`${o}@2x${a}`),scale:2/3},{outputPath:e.join(i,`${o}@1x${a}`),scale:1/3}].filter(e=>r.overwrite||!t.existsSync(e.outputPath));if(c.length===0)return;let{default:l}=await import(`sharp`),u;try{u=(await l(n).metadata()).width}catch(e){console.error(`[image-generator] Failed to read metadata for ${n}`,e);return}if(!u){console.error(`[image-generator] Skipping ${n}; image width could not be read.`);return}await Promise.all(c.map(e=>s({file:n,outputPath:e.outputPath,sharp:l,width:Math.round(u*e.scale)})))}async function s(e){try{console.log(`[image-generator] Generating ${e.outputPath} (${e.width}w)`),await e.sharp(e.file).resize({width:e.width}).toFile(e.outputPath)}catch(t){console.error(`[image-generator] Failed to process ${e.file} for ${e.outputPath}`,t)}}export{r as imageGenerator};