@coreframe/scripts 0.1.32 → 0.1.34
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/coreframe.d.ts +56 -0
- package/dist/coreframe.js +2 -2
- package/dist/dev.d.ts +2 -0
- package/dist/dev.js +1 -1
- package/dist/recipes/apply.d.ts +26 -0
- package/dist/recipes/apply.js +2 -0
- package/dist/recipes/list.d.ts +14 -0
- package/dist/recipes/list.js +1 -0
- package/dist/recipes/manifest.d.ts +14 -0
- package/dist/recipes/manifest.js +1 -0
- package/dist/recipes/source.d.ts +22 -0
- package/dist/recipes/source.js +1 -0
- package/dist/tauri-dev-output.d.ts +19 -0
- package/dist/tauri-dev-output.js +2 -0
- package/dist/upgrade/ensure-template-remote.d.ts +2 -0
- package/dist/upgrade/ensure-template-remote.js +1 -1
- package/package.json +3 -2
package/dist/coreframe.d.ts
CHANGED
|
@@ -96,6 +96,7 @@ declare const coreframeCli: Partial<import("cmd-ts/dist/cjs/argparser").Register
|
|
|
96
96
|
platform: "ios" | "android" | "web" | "desktop" | undefined;
|
|
97
97
|
device: string | undefined;
|
|
98
98
|
port: number | undefined;
|
|
99
|
+
verbose: boolean;
|
|
99
100
|
};
|
|
100
101
|
} | {
|
|
101
102
|
command: "upgrade";
|
|
@@ -125,6 +126,24 @@ declare const coreframeCli: Partial<import("cmd-ts/dist/cjs/argparser").Register
|
|
|
125
126
|
apply: boolean;
|
|
126
127
|
};
|
|
127
128
|
};
|
|
129
|
+
} | {
|
|
130
|
+
command: "recipes";
|
|
131
|
+
args: {
|
|
132
|
+
command: "apply";
|
|
133
|
+
args: {
|
|
134
|
+
recipe: string;
|
|
135
|
+
target: string | undefined;
|
|
136
|
+
remote: string;
|
|
137
|
+
noFetch: boolean;
|
|
138
|
+
};
|
|
139
|
+
} | {
|
|
140
|
+
command: "list";
|
|
141
|
+
args: {
|
|
142
|
+
target: string | undefined;
|
|
143
|
+
remote: string;
|
|
144
|
+
noFetch: boolean;
|
|
145
|
+
};
|
|
146
|
+
};
|
|
128
147
|
} | {
|
|
129
148
|
command: "db";
|
|
130
149
|
args: {
|
|
@@ -268,6 +287,7 @@ declare const coreframeCli: Partial<import("cmd-ts/dist/cjs/argparser").Register
|
|
|
268
287
|
platform: "ios" | "android" | "web" | "desktop" | undefined;
|
|
269
288
|
device: string | undefined;
|
|
270
289
|
port: number | undefined;
|
|
290
|
+
verbose: boolean;
|
|
271
291
|
};
|
|
272
292
|
} | {
|
|
273
293
|
command: "upgrade";
|
|
@@ -297,6 +317,24 @@ declare const coreframeCli: Partial<import("cmd-ts/dist/cjs/argparser").Register
|
|
|
297
317
|
apply: boolean;
|
|
298
318
|
};
|
|
299
319
|
};
|
|
320
|
+
} | {
|
|
321
|
+
command: "recipes";
|
|
322
|
+
args: {
|
|
323
|
+
command: "apply";
|
|
324
|
+
args: {
|
|
325
|
+
recipe: string;
|
|
326
|
+
target: string | undefined;
|
|
327
|
+
remote: string;
|
|
328
|
+
noFetch: boolean;
|
|
329
|
+
};
|
|
330
|
+
} | {
|
|
331
|
+
command: "list";
|
|
332
|
+
args: {
|
|
333
|
+
target: string | undefined;
|
|
334
|
+
remote: string;
|
|
335
|
+
noFetch: boolean;
|
|
336
|
+
};
|
|
337
|
+
};
|
|
300
338
|
} | {
|
|
301
339
|
command: "db";
|
|
302
340
|
args: {
|
|
@@ -406,6 +444,15 @@ declare const coreframeCli: Partial<import("cmd-ts/dist/cjs/argparser").Register
|
|
|
406
444
|
command: "sync-coreframe-packages";
|
|
407
445
|
value: void;
|
|
408
446
|
};
|
|
447
|
+
} | {
|
|
448
|
+
command: "recipes";
|
|
449
|
+
value: {
|
|
450
|
+
command: "apply";
|
|
451
|
+
value: void;
|
|
452
|
+
} | {
|
|
453
|
+
command: "list";
|
|
454
|
+
value: void;
|
|
455
|
+
};
|
|
409
456
|
} | {
|
|
410
457
|
command: "db";
|
|
411
458
|
value: {
|
|
@@ -506,6 +553,15 @@ declare const coreframeCli: Partial<import("cmd-ts/dist/cjs/argparser").Register
|
|
|
506
553
|
command: "sync-coreframe-packages";
|
|
507
554
|
value: void;
|
|
508
555
|
};
|
|
556
|
+
} | {
|
|
557
|
+
command: "recipes";
|
|
558
|
+
value: {
|
|
559
|
+
command: "apply";
|
|
560
|
+
value: void;
|
|
561
|
+
} | {
|
|
562
|
+
command: "list";
|
|
563
|
+
value: void;
|
|
564
|
+
};
|
|
509
565
|
} | {
|
|
510
566
|
command: "db";
|
|
511
567
|
value: {
|
package/dist/coreframe.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{addAsset as e,buildAssets as t,checkAssets as n,printAssetResult as r,publishAssets as i}from"./assets.js";import{runDrizzleKitCommand as a}from"./db/drizzle-kit.js";import{seedLocalDb as o}from"./db/seed.js";import{migrateLocalDb as s}from"./db/migrate.js";import{resetLocalDb as c}from"./db/reset.js";import{setupLocalDb as l}from"./db/setup.js";import{ensureLocalDb as u}from"./db/ensure.js";import{migrateHeldMigrations as d}from"./db/migrate-held.js";import{checkSchemaPush as f}from"./db/schema-check.js";import{deployEnvironments as p,tauriReleasePlatforms as m}from"./deploy/config.js";import{discoverStagingUrl as h,reassignStagingHostname as g}from"./staging.js";import{discardPendingWorkerSecret as _,inspectWorkerEnvironment as v,queueWorkerSecret as y}from"./worker-environment.js";import{deployProject as b}from"./deploy.js";import{checkDeployMigrations as x}from"./deploy/check-migrations.js";import{devPlatforms as S,runDevServer as C}from"./dev.js";import{run as w}from"./runner.js";import{typecheckProject as T}from"./typecheck.js";import{checkUpgradeSkillCurrent as E}from"./upgrade/check-skill-current.js";import{ensureTemplateRemote as D}from"./upgrade/ensure-template-remote.js";import{fastForwardTemplateFiles as O}from"./upgrade/fast-forward-template-files.js";import{syncCoreframePackages as k}from"./upgrade/sync-coreframe-packages.js";import*as A from"@clack/prompts";import{array as j,command as M,extendType as N,flag as P,multioption as F,number as I,oneOf as L,option as R,optional as z,positional as B,rest as V,string as H,subcommands as U}from"cmd-ts";const W=[`Cookies and sessions are origin-scoped.`,`Exact-host passkeys may require re-registration unless a stable eligible parent RP ID was configured in advance.`,`External OAuth callbacks such as Google may need updating.`,`Database data and private backend resources are unchanged.`],G=N(H,{displayName:`widths`,description:`Comma-separated responsive variant widths.`,async from(e){let t=e.split(`,`).map(e=>Number(e));if(t.length===0||t.some(e=>!Number.isInteger(e)||e<=0)||t.some((e,n)=>n>0&&e<=t[n-1]))throw Error(`Widths must be positive, unique, strictly ascending integers.`);return t}}),K=U({name:`coreframe`,cmds:{assets:U({name:`assets`,cmds:{add:M({name:`add`,args:{file:B({type:H,displayName:`file`,description:`Source image to add to the asset library.`}),id:R({long:`id`,type:H,description:`Logical asset ID, such as blog/my-post/hero.`}),alt:R({long:`alt`,type:H,description:`Required alt text for the asset.`}),variantWidths:R({long:`widths`,type:z(G),description:`Generate exactly these comma-separated widths instead of the default ladder.`}),json:P({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({alt:t,file:n,id:i,json:a,variantWidths:o})=>r(await e({alt:t,file:n,id:i,json:a,variantWidths:o}),a)}),build:M({name:`build`,args:{id:R({long:`id`,type:z(H),description:`Build only one logical asset ID.`}),noPull:P({long:`no-pull`,description:`Do not perform targeted Git LFS pulls for missing source objects.`,defaultValue:()=>!1}),json:P({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({id:e,json:n,noPull:i})=>r(await t({id:e,json:n,pull:!i}),n)}),check:M({name:`check`,args:{fix:P({long:`fix`,description:`Build missing generated variants when possible.`,defaultValue:()=>!1}),json:P({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({fix:e,json:t})=>{let i=await n({fix:e,json:t});r(i,t),i.ok||(process.exitCode=1)}}),publish:M({name:`publish`,args:{outputDir:R({long:`output-dir`,type:z(H),description:`Root directory for additive local publish output. Defaults to COREFRAME_ASSETS_PUBLISH_DIR or release-upload.`}),json:P({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,outputDir:t})=>{let n=await i({json:e,outputDir:t});r(n,e),n.ok||(process.exitCode=1)}}),status:M({name:`status`,args:{json:P({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await n({json:e});r(t,e),t.ok||(process.exitCode=1)}})}}),deploy:M({name:`deploy`,args:{environment:B({type:L(p),displayName:`environment`,description:`Deploy to the staging or production environment.`}),runMigrations:P({long:`run-migrations`,description:`Run pending deploy-safe database migrations before deploying.`,defaultValue:()=>!1}),skipMigrations:P({long:`skip-migrations`,description:`Deploy without running pending deploy-safe database migrations.`,defaultValue:()=>!1}),skipPostDeployChecks:P({long:`skip-post-deploy-checks`,description:`Skip post-deploy checks after Cloudflare deployment.`,defaultValue:()=>!1}),tauriLocalPlatforms:F({long:`tauri-local-platform`,type:j(L(m)),description:`Build one Tauri release platform locally. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowName:R({long:`tauri-workflow-name`,type:z(H),description:`GitHub Actions workflow file or name for remote Tauri release builds.`}),tauriWorkflowPlatforms:F({long:`tauri-workflow-platform`,type:j(L(m)),description:`Build one Tauri release platform with GitHub Actions. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowRef:R({long:`tauri-workflow-ref`,type:z(H),description:`Git ref used when dispatching remote Tauri release builds.`}),yes:P({long:`yes`,short:`y`,description:`Approve the production deployment confirmation.`,defaultValue:()=>!1})},handler:({environment:e,runMigrations:t,skipMigrations:n,skipPostDeployChecks:r,tauriLocalPlatforms:i,tauriWorkflowName:a,tauriWorkflowPlatforms:o,tauriWorkflowRef:s,yes:c})=>b([e,...t?[`--run-migrations`]:[],...n?[`--skip-migrations`]:[],...r?[`--skip-post-deploy-checks`]:[],...i.flatMap(e=>[`--tauri-local-platform`,e]),...a?[`--tauri-workflow-name`,a]:[],...o.flatMap(e=>[`--tauri-workflow-platform`,e]),...s?[`--tauri-workflow-ref`,s]:[],...c?[`--yes`]:[]])}),staging:U({name:`staging`,cmds:{reassign:M({name:`reassign`,args:{json:P({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await g();if(e){console.log(JSON.stringify({...t,notices:W}));return}console.log(t.url),console.error(`Staging hostname reassigned. ${W.join(` `)}`)}}),url:M({name:`url`,args:{json:P({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await h();console.log(e?JSON.stringify({url:t}):t)}})}}),secrets:U({name:`secrets`,cmds:{status:M({name:`status`,args:{environment:B({type:z(L(p)),displayName:`environment`,description:`Inspect staging, production, or both when omitted.`}),json:P({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({environment:e,json:t})=>{let n=await v({environment:e});console.log(t?JSON.stringify(n):q(n))}}),set:M({name:`set`,args:{environment:B({type:L(p),displayName:`environment`,description:`Worker environment to update on its next deploy.`}),name:B({type:H,displayName:`name`,description:`Declared Worker secret name.`})},handler:async({environment:e,name:t})=>{await y({environment:e,name:t,value:await J(t)}),console.log(`Queued ${t} for ${e}. Run coreframe deploy ${e} to apply.`)}}),discard:M({name:`discard`,args:{environment:B({type:L(p),displayName:`environment`,description:`Worker environment with a queued secret update.`}),name:B({type:H,displayName:`name`,description:`Declared Worker secret name.`})},handler:async({environment:e,name:t})=>{let n=await _({environment:e,name:t});console.log(n?`Discarded the queued ${t} update for ${e}.`:`No ${t} update is queued for ${e}.`)}})}}),typecheck:M({name:`typecheck`,args:{},handler:T}),dev:M({name:`dev`,args:{https:P({long:`https`,description:`Serve the web app over locally trusted HTTPS.`,defaultValue:()=>!1}),host:R({long:`host`,type:z(H),description:`Host address for the web development server.`}),managed:P({long:`managed`,description:`Run managed checkout synchronization even without an interactive terminal.`,defaultValue:()=>!1}),noManaged:P({long:`no-managed`,description:`Run without managed checkout synchronization for this invocation.`,defaultValue:()=>!1}),platform:B({type:z(L(S)),displayName:`platform`,description:`Development target platform. Defaults to web.`}),device:B({type:z(H),displayName:`device`,description:`Device name or ID for iOS or Android development.`}),port:R({long:`port`,type:z(I),description:`Port for the web development server.`})},handler:({device:e,host:t,https:n,managed:r,noManaged:i,platform:a,port:o})=>C({device:e,host:t,https:n,managed:r,noManaged:i,platform:a??`web`,webPort:o})}),upgrade:U({name:`upgrade`,cmds:{"ensure-template-remote":M({name:`ensure-template-remote`,args:{remote:R({long:`remote`,type:H,defaultValue:()=>`template`,description:`Remote name to ensure.`}),noFetch:P({long:`no-fetch`,description:`Do not fetch the remote after ensuring it exists.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t})=>D({fetch:!e,remote:t})}),"check-skill-current":M({name:`check-skill-current`,args:{target:R({long:`target`,type:H,description:`Target Coreframe template git ref.`}),apply:P({long:`apply`,description:`Replace the local upgrade skill with the target version when it differs.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>{process.exitCode=E({apply:e,target:t})}}),"fast-forward-template-files":M({name:`fast-forward-template-files`,args:{target:R({long:`target`,type:H,description:`Target Coreframe template git ref.`}),base:R({long:`base`,type:z(H),description:`Previous Coreframe template git ref. Defaults to package.json engines.coreframe.`}),apply:P({long:`apply`,description:`Write clean fast-forwards to the worktree.`,defaultValue:()=>!1})},handler:({apply:e,base:t,target:n})=>O({apply:e,base:t,target:n})}),"sync-coreframe-packages":M({name:`sync-coreframe-packages`,args:{target:R({long:`target`,type:H,description:`Target Coreframe template git ref.`}),apply:P({long:`apply`,description:`Update existing published Coreframe dependency specifications.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>k({apply:e,target:t})})}}),db:U({name:`db`,cmds:{ensure:M({name:`ensure`,args:{},handler:u}),generate:M({name:`generate`,args:{args:V({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit generate.`})},handler:({args:e})=>a(`generate`,e)}),migrate:M({name:`migrate`,args:{args:V({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit migrate.`})},handler:({args:e})=>a(`migrate`,e)}),"migrate-held":M({name:`migrate-held`,args:{confirm:R({long:`confirm`,type:z(L([`run-held-migrations`])),description:`Required confirmation value for held migrations.`})},handler:({confirm:e})=>d({argv:e?[`--confirm=${e}`]:[]})}),"migrate-local":M({name:`migrate-local`,args:{},handler:s}),"migrations-check":M({name:`migrations-check`,args:{},handler:x}),reset:M({name:`reset`,args:{},handler:c}),seed:M({name:`seed`,args:{},handler:()=>o()}),"schema-check":M({name:`schema-check`,args:{seed:P({long:`seed`,description:`Run the configured project seed against the throwaway database.`,defaultValue:()=>!1})},handler:({seed:e})=>f({seed:e})}),setup:M({name:`setup`,args:{},handler:()=>l()}),studio:M({name:`studio`,args:{args:V({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit studio.`})},handler:({args:e})=>a(`studio`,e)})}})}});import.meta.main&&w(K);function q(e){if(e.entries.length===0)return`No Worker environment values are declared in coreframe.config.ts.`;let t=e.entries.map(e=>[e.name,e.kind,e.local===`override`?`override`:`built-in default`,e.deployed.staging.replaceAll(`_`,` `),e.deployed.production.replaceAll(`_`,` `)]),n=[`Name`,`Kind`,`Local`,`Staging`,`Production`],r=n.map((e,n)=>Math.max(e.length,...t.map(e=>e[n].length))),i=e=>e.map((e,t)=>e.padEnd(r[t])).join(` `).trimEnd();return[i(n),i(r.map(e=>`-`.repeat(e))),...t].join(`
|
|
3
|
-
`)}async function
|
|
2
|
+
import{addAsset as e,buildAssets as t,checkAssets as n,printAssetResult as r,publishAssets as i}from"./assets.js";import{runDrizzleKitCommand as a}from"./db/drizzle-kit.js";import{seedLocalDb as o}from"./db/seed.js";import{migrateLocalDb as s}from"./db/migrate.js";import{resetLocalDb as c}from"./db/reset.js";import{setupLocalDb as l}from"./db/setup.js";import{ensureLocalDb as u}from"./db/ensure.js";import{migrateHeldMigrations as d}from"./db/migrate-held.js";import{checkSchemaPush as f}from"./db/schema-check.js";import{deployEnvironments as p,tauriReleasePlatforms as m}from"./deploy/config.js";import{discoverStagingUrl as h,reassignStagingHostname as g}from"./staging.js";import{discardPendingWorkerSecret as _,inspectWorkerEnvironment as v,queueWorkerSecret as y}from"./worker-environment.js";import{deployProject as b}from"./deploy.js";import{checkDeployMigrations as x}from"./deploy/check-migrations.js";import{devPlatforms as S,runDevServer as C}from"./dev.js";import{validateRecipeName as w}from"./recipes/manifest.js";import{ensureTemplateRemote as T}from"./upgrade/ensure-template-remote.js";import{applyRecipe as E,printAppliedRecipe as D}from"./recipes/apply.js";import{listRecipes as O,printRecipeCatalog as k}from"./recipes/list.js";import{run as A}from"./runner.js";import{typecheckProject as j}from"./typecheck.js";import{checkUpgradeSkillCurrent as M}from"./upgrade/check-skill-current.js";import{fastForwardTemplateFiles as N}from"./upgrade/fast-forward-template-files.js";import{syncCoreframePackages as P}from"./upgrade/sync-coreframe-packages.js";import*as F from"@clack/prompts";import{array as I,command as L,extendType as R,flag as z,multioption as B,number as V,oneOf as H,option as U,optional as W,positional as G,rest as K,string as q,subcommands as J}from"cmd-ts";const Y=[`Cookies and sessions are origin-scoped.`,`Exact-host passkeys may require re-registration unless a stable eligible parent RP ID was configured in advance.`,`External OAuth callbacks such as Google may need updating.`,`Database data and private backend resources are unchanged.`],X=R(q,{displayName:`widths`,description:`Comma-separated responsive variant widths.`,async from(e){let t=e.split(`,`).map(e=>Number(e));if(t.length===0||t.some(e=>!Number.isInteger(e)||e<=0)||t.some((e,n)=>n>0&&e<=t[n-1]))throw Error(`Widths must be positive, unique, strictly ascending integers.`);return t}}),Z=R(q,{displayName:`recipe`,description:`Coreframe recipe name, such as yam-db.`,async from(e){return w(e)}}),Q=J({name:`coreframe`,cmds:{assets:J({name:`assets`,cmds:{add:L({name:`add`,args:{file:G({type:q,displayName:`file`,description:`Source image to add to the asset library.`}),id:U({long:`id`,type:q,description:`Logical asset ID, such as blog/my-post/hero.`}),alt:U({long:`alt`,type:q,description:`Required alt text for the asset.`}),variantWidths:U({long:`widths`,type:W(X),description:`Generate exactly these comma-separated widths instead of the default ladder.`}),json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({alt:t,file:n,id:i,json:a,variantWidths:o})=>r(await e({alt:t,file:n,id:i,json:a,variantWidths:o}),a)}),build:L({name:`build`,args:{id:U({long:`id`,type:W(q),description:`Build only one logical asset ID.`}),noPull:z({long:`no-pull`,description:`Do not perform targeted Git LFS pulls for missing source objects.`,defaultValue:()=>!1}),json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({id:e,json:n,noPull:i})=>r(await t({id:e,json:n,pull:!i}),n)}),check:L({name:`check`,args:{fix:z({long:`fix`,description:`Build missing generated variants when possible.`,defaultValue:()=>!1}),json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({fix:e,json:t})=>{let i=await n({fix:e,json:t});r(i,t),i.ok||(process.exitCode=1)}}),publish:L({name:`publish`,args:{outputDir:U({long:`output-dir`,type:W(q),description:`Root directory for additive local publish output. Defaults to COREFRAME_ASSETS_PUBLISH_DIR or release-upload.`}),json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e,outputDir:t})=>{let n=await i({json:e,outputDir:t});r(n,e),n.ok||(process.exitCode=1)}}),status:L({name:`status`,args:{json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await n({json:e});r(t,e),t.ok||(process.exitCode=1)}})}}),deploy:L({name:`deploy`,args:{environment:G({type:H(p),displayName:`environment`,description:`Deploy to the staging or production environment.`}),runMigrations:z({long:`run-migrations`,description:`Run pending deploy-safe database migrations before deploying.`,defaultValue:()=>!1}),skipMigrations:z({long:`skip-migrations`,description:`Deploy without running pending deploy-safe database migrations.`,defaultValue:()=>!1}),skipPostDeployChecks:z({long:`skip-post-deploy-checks`,description:`Skip post-deploy checks after Cloudflare deployment.`,defaultValue:()=>!1}),tauriLocalPlatforms:B({long:`tauri-local-platform`,type:I(H(m)),description:`Build one Tauri release platform locally. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowName:U({long:`tauri-workflow-name`,type:W(q),description:`GitHub Actions workflow file or name for remote Tauri release builds.`}),tauriWorkflowPlatforms:B({long:`tauri-workflow-platform`,type:I(H(m)),description:`Build one Tauri release platform with GitHub Actions. Repeat for multiple platforms.`,defaultValue:()=>[]}),tauriWorkflowRef:U({long:`tauri-workflow-ref`,type:W(q),description:`Git ref used when dispatching remote Tauri release builds.`}),yes:z({long:`yes`,short:`y`,description:`Approve the production deployment confirmation.`,defaultValue:()=>!1})},handler:({environment:e,runMigrations:t,skipMigrations:n,skipPostDeployChecks:r,tauriLocalPlatforms:i,tauriWorkflowName:a,tauriWorkflowPlatforms:o,tauriWorkflowRef:s,yes:c})=>b([e,...t?[`--run-migrations`]:[],...n?[`--skip-migrations`]:[],...r?[`--skip-post-deploy-checks`]:[],...i.flatMap(e=>[`--tauri-local-platform`,e]),...a?[`--tauri-workflow-name`,a]:[],...o.flatMap(e=>[`--tauri-workflow-platform`,e]),...s?[`--tauri-workflow-ref`,s]:[],...c?[`--yes`]:[]])}),staging:J({name:`staging`,cmds:{reassign:L({name:`reassign`,args:{json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await g();if(e){console.log(JSON.stringify({...t,notices:Y}));return}console.log(t.url),console.error(`Staging hostname reassigned. ${Y.join(` `)}`)}}),url:L({name:`url`,args:{json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({json:e})=>{let t=await h();console.log(e?JSON.stringify({url:t}):t)}})}}),secrets:J({name:`secrets`,cmds:{status:L({name:`status`,args:{environment:G({type:W(H(p)),displayName:`environment`,description:`Inspect staging, production, or both when omitted.`}),json:z({long:`json`,description:`Print machine-readable JSON.`,defaultValue:()=>!1})},handler:async({environment:e,json:t})=>{let n=await v({environment:e});console.log(t?JSON.stringify(n):$(n))}}),set:L({name:`set`,args:{environment:G({type:H(p),displayName:`environment`,description:`Worker environment to update on its next deploy.`}),name:G({type:q,displayName:`name`,description:`Declared Worker secret name.`})},handler:async({environment:e,name:t})=>{await y({environment:e,name:t,value:await ee(t)}),console.log(`Queued ${t} for ${e}. Run coreframe deploy ${e} to apply.`)}}),discard:L({name:`discard`,args:{environment:G({type:H(p),displayName:`environment`,description:`Worker environment with a queued secret update.`}),name:G({type:q,displayName:`name`,description:`Declared Worker secret name.`})},handler:async({environment:e,name:t})=>{let n=await _({environment:e,name:t});console.log(n?`Discarded the queued ${t} update for ${e}.`:`No ${t} update is queued for ${e}.`)}})}}),typecheck:L({name:`typecheck`,args:{},handler:j}),dev:L({name:`dev`,args:{https:z({long:`https`,description:`Serve the web app over locally trusted HTTPS.`,defaultValue:()=>!1}),host:U({long:`host`,type:W(q),description:`Host address for the web development server.`}),managed:z({long:`managed`,description:`Run managed checkout synchronization even without an interactive terminal.`,defaultValue:()=>!1}),noManaged:z({long:`no-managed`,description:`Run without managed checkout synchronization for this invocation.`,defaultValue:()=>!1}),platform:G({type:W(H(S)),displayName:`platform`,description:`Development target platform. Defaults to web.`}),device:G({type:W(q),displayName:`device`,description:`Device name or ID for iOS or Android development.`}),port:U({long:`port`,type:W(V),description:`Port for the web development server.`}),verbose:z({long:`verbose`,description:`Show the full native development output.`,defaultValue:()=>!1})},handler:({device:e,host:t,https:n,managed:r,noManaged:i,platform:a,port:o,verbose:s})=>C({device:e,host:t,https:n,managed:r,noManaged:i,platform:a??`web`,verbose:s,webPort:o})}),upgrade:J({name:`upgrade`,cmds:{"ensure-template-remote":L({name:`ensure-template-remote`,args:{remote:U({long:`remote`,type:q,defaultValue:()=>`template`,description:`Remote name to ensure.`}),noFetch:z({long:`no-fetch`,description:`Do not fetch the remote after ensuring it exists.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t})=>T({fetch:!e,remote:t})}),"check-skill-current":L({name:`check-skill-current`,args:{target:U({long:`target`,type:q,description:`Target Coreframe template git ref.`}),apply:z({long:`apply`,description:`Replace the local upgrade skill with the target version when it differs.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>{process.exitCode=M({apply:e,target:t})}}),"fast-forward-template-files":L({name:`fast-forward-template-files`,args:{target:U({long:`target`,type:q,description:`Target Coreframe template git ref.`}),base:U({long:`base`,type:W(q),description:`Previous Coreframe template git ref. Defaults to package.json engines.coreframe.`}),apply:z({long:`apply`,description:`Write clean fast-forwards to the worktree.`,defaultValue:()=>!1})},handler:({apply:e,base:t,target:n})=>N({apply:e,base:t,target:n})}),"sync-coreframe-packages":L({name:`sync-coreframe-packages`,args:{target:U({long:`target`,type:q,description:`Target Coreframe template git ref.`}),apply:z({long:`apply`,description:`Update existing published Coreframe dependency specifications.`,defaultValue:()=>!1})},handler:({apply:e,target:t})=>P({apply:e,target:t})})}}),recipes:J({name:`recipes`,cmds:{apply:L({name:`apply`,args:{recipe:G({type:Z,displayName:`recipe`,description:`Recipe to prepare and apply.`}),target:U({long:`target`,type:W(q),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:U({long:`remote`,type:q,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:z({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,recipe:t,remote:n,target:r})=>D(E({fetch:!e,name:t,remote:n,target:r}))}),list:L({name:`list`,args:{target:U({long:`target`,type:W(q),description:`Coreframe Git ref. Defaults to package.json engines.coreframe.`}),remote:U({long:`remote`,type:q,defaultValue:()=>`template`,description:`Coreframe Git remote name.`}),noFetch:z({long:`no-fetch`,description:`Use already-fetched recipe refs without fetching the remote.`,defaultValue:()=>!1})},handler:({noFetch:e,remote:t,target:n})=>k(O({fetch:!e,remote:t,target:n}))})}}),db:J({name:`db`,cmds:{ensure:L({name:`ensure`,args:{},handler:u}),generate:L({name:`generate`,args:{args:K({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit generate.`})},handler:({args:e})=>a(`generate`,e)}),migrate:L({name:`migrate`,args:{args:K({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit migrate.`})},handler:({args:e})=>a(`migrate`,e)}),"migrate-held":L({name:`migrate-held`,args:{confirm:U({long:`confirm`,type:W(H([`run-held-migrations`])),description:`Required confirmation value for held migrations.`})},handler:({confirm:e})=>d({argv:e?[`--confirm=${e}`]:[]})}),"migrate-local":L({name:`migrate-local`,args:{},handler:s}),"migrations-check":L({name:`migrations-check`,args:{},handler:x}),reset:L({name:`reset`,args:{},handler:c}),seed:L({name:`seed`,args:{},handler:()=>o()}),"schema-check":L({name:`schema-check`,args:{seed:z({long:`seed`,description:`Run the configured project seed against the throwaway database.`,defaultValue:()=>!1})},handler:({seed:e})=>f({seed:e})}),setup:L({name:`setup`,args:{},handler:()=>l()}),studio:L({name:`studio`,args:{args:K({displayName:`drizzle-kit args`,description:`Additional arguments passed to drizzle-kit studio.`})},handler:({args:e})=>a(`studio`,e)})}})}});import.meta.main&&A(Q);function $(e){if(e.entries.length===0)return`No Worker environment values are declared in coreframe.config.ts.`;let t=e.entries.map(e=>[e.name,e.kind,e.local===`override`?`override`:`built-in default`,e.deployed.staging.replaceAll(`_`,` `),e.deployed.production.replaceAll(`_`,` `)]),n=[`Name`,`Kind`,`Local`,`Staging`,`Production`],r=n.map((e,n)=>Math.max(e.length,...t.map(e=>e[n].length))),i=e=>e.map((e,t)=>e.padEnd(r[t])).join(` `).trimEnd();return[i(n),i(r.map(e=>`-`.repeat(e))),...t].join(`
|
|
3
|
+
`)}async function ee(e){if(!process.stdin.isTTY){let e=``;for await(let t of process.stdin)e+=t.toString();return e.replace(/\r?\n$/,``)}let t=await F.password({message:`Enter the new value for ${e}`});if(F.isCancel(t))throw F.cancel(`Secret update cancelled.`),Error(`Secret update cancelled.`);return t}export{Q as coreframeCli};
|
package/dist/dev.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ type DevServerOptions = {
|
|
|
12
12
|
managed?: boolean;
|
|
13
13
|
noManaged?: boolean;
|
|
14
14
|
platform?: DevPlatform;
|
|
15
|
+
verbose?: boolean;
|
|
15
16
|
webPort?: number;
|
|
16
17
|
};
|
|
17
18
|
declare const devPlatforms: readonly ["web", "desktop", "ios", "android"];
|
|
@@ -28,6 +29,7 @@ declare function runDevServer({
|
|
|
28
29
|
managed,
|
|
29
30
|
noManaged,
|
|
30
31
|
platform,
|
|
32
|
+
verbose,
|
|
31
33
|
webPort
|
|
32
34
|
}?: DevServerOptions): Promise<void>;
|
|
33
35
|
//#endregion
|
package/dist/dev.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{readProjectConfig as e}from"./config.js";import{fs as t,net as n}from"./environment.js";import{ProjectPostgresAlreadyRunningError as r,startProjectPostgres as i,stopProjectPostgres as a}from"./db/local-postgres.js";import o from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{resolveMobileDevHost as s,selectMobileDevDevice as c}from"./dev-device.js";import{devHttpsCertEnv as
|
|
2
|
+
import{readProjectConfig as e}from"./config.js";import{fs as t,net as n}from"./environment.js";import{ProjectPostgresAlreadyRunningError as r,startProjectPostgres as i,stopProjectPostgres as a}from"./db/local-postgres.js";import o from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{resolveMobileDevHost as s,selectMobileDevDevice as c}from"./dev-device.js";import{devHttpsCertEnv as l,devHttpsKeyEnv as u,prepareDevHttps as d}from"./dev-https.js";import{acquireDevLock as f}from"./dev-lock.js";import{managedDevEnv as p}from"./managed-dev-protocol.js";import{isManagedDevCheckout as m,isPrimaryCheckout as ee}from"./managed-dev.js";import{createTauriDevOutput as te}from"./tauri-dev-output.js";import h from"node:path";import g from"nano-spawn";import*as _ from"@clack/prompts";import v from"node:process";import*as ne from"node:readline";import{createPrefixStream as y,supervise as b}from"procband";const x=[`web`,`desktop`,`ios`,`android`];function S(e){let t=e.dev?.platforms??[`web`];for(let e of t)if(!x.includes(e))throw Error(`Invalid development platform "${String(e)}". Expected one of: ${x.join(`, `)}.`);return[...new Set(t)]}const C=h.resolve(`node_modules`,`.bin`),w=v.platform===`win32`?`pnpm.cmd`:`pnpm`,T=v.platform===`win32`?`portless.cmd`:`portless`,E=v.platform===`win32`?`react-router.cmd`:`react-router`,D=v.platform===`win32`?`turso.cmd`:`turso`;async function O({cwd:r=v.cwd(),device:i,env:a=v.env,host:x,https:S=!1,input:O=v.stdin,interactive:N=v.stdin.isTTY===!0,managed:P=!1,noManaged:F=!1,platform:I=`web`,verbose:L=!1,webPort:R}={}){let z=a.PATH??a.Path??``,B=I===`web`?M(R??a.COREFRAME_WEB_PORT):void 0,V,H,U,W=!1,G=a;if(P&&F)throw Error(`Cannot use --managed and --no-managed together.`);if(S&&I!==`web`)throw Error(`Local HTTPS is only supported for the web development platform.`);if(i!==void 0&&I!==`ios`&&I!==`android`)throw Error(`A device name or ID is only supported for iOS or Android development.`);if(I===`web`&&a.TAURI_ENV_PLATFORM!==void 0&&a.COREFRAME_TAURI_DEV!==`1`){let e=a.TAURI_ENV_PLATFORM===`ios`||a.TAURI_ENV_PLATFORM===`android`?a.TAURI_ENV_PLATFORM:`desktop`;throw Error(`Direct Tauri development is not supported. Run \`pnpm dev ${e}\` instead.`)}let K=await f({cwd:r,interactive:N});if(K)try{let f=I===`ios`||I===`android`?I:void 0,M=f?await c({env:a,interactive:N,platform:f,target:i}):void 0,R=f&&M?await s({device:M,host:x,interactive:N,platform:f}):void 0,J=R?!0:x,Y=await e({cwd:r}),X=I===`web`&&a.PORTLESS!==`0`&&a.TAURI_ENV_PLATFORM===void 0&&await ee(r),Z=S&&!X?await d({cwd:r}):void 0;G={...a,...I===`web`?void 0:{COREFRAME_TAURI_DEV:`1`,TAURI_ENV_PLATFORM:ie(I),...R?{TAURI_DEV_HOST:R}:void 0},...Z?{[l]:Z.cert,[u]:Z.key}:void 0};let Q=async()=>{let e=!1,t=N?ne.createInterface({input:O}):void 0;t?.on(`line`,t=>{t.trim().toLowerCase()!==`r`||!U||e||(e=!0,U.kill(`SIGTERM`)?_.log.info(`Restarting the Vite development server.`):e=!1)}),t&&_.log.info(`Press r + Enter to restart the Vite development server.`);try{for(;;){e=!1,U=b({name:`web`,command:X?T:E,args:X?ae({host:J,port:B}):j({host:J,port:B}),cwd:r,env:{...G,CLOUDFLARE_ENV:`development`,PATH:C+h.delimiter+z}}),await U.wait();let t=U;if(U=void 0,!e){W||await t.expectSuccess();return}}}finally{t?.close()}},$=async()=>{if(I===`web`){await Q();return}let e=Q().then(()=>{if(!W)throw Error(`The Vite development server stopped while Tauri was still running.`)}),t,n;if(I===`ios`&&!L){n=y({label:`ios`}),n.pipe(v.stdout,{end:!1});try{t=await te({output:n}),_.log.info(`Full iOS log: ${t.logFile}`)}catch{n.end(),n=void 0,_.log.warn(`Could not create the temporary iOS log; showing full Tauri output.`)}}V=g(w,re(I,M?.name,R),{cwd:r,env:a,stdio:t?[`inherit`,`pipe`,`pipe`]:`inherit`});let i=t?.consume(V),o=V.catch(async e=>{throw W||(await i,await t?.reportFailure()),e});try{await Promise.race([e,o])}finally{W=!0,U?.kill(`SIGTERM`),(await V.nodeChildProcess.catch(()=>void 0))?.kill(`SIGTERM`),await Promise.allSettled([e,V,i]),await t?.close(),n?.end(),V=void 0}};if((P||N&&!F)&&await m(r)&&(G={...G,[p]:`1`}),Y.database?.dialect===`sqlite`){let e=await n.getAvailablePort(),i=h.resolve(r,`.coreframe`),o=h.join(i,`turso.db`);await t.mkdir(i,{recursive:!0}),G={...G,TURSO_DATABASE_URL:`http://127.0.0.1:${e}`,TURSO_AUTH_TOKEN:`dev`},H=b({name:`turso`,command:D,args:[`dev`,`--port`,String(e),`--db-file`,o],cwd:r,env:a}),await H.waitFor(`listening`),await b({name:`db`,command:w,args:[`db`,`ensure`],cwd:r,env:G,prefix:!1}).expectSuccess()}if(A(Y)){let e=y({label:`postgres`});e.pipe(v.stdout,{end:!1});try{try{var q=o();let t=await k({config:Y,cwd:r,env:G,interactive:N,postgresOutput:e,takeoverApproved:K.takeoverApproved});if(!t)return;q.a(t),G=t.env,await b({name:`db`,command:w,args:[`db`,`ensure`],cwd:r,env:G,prefix:!1}).expectSuccess(),await $()}catch(e){q.e=e}finally{await q.d()}}finally{e.end()}return}await $()}finally{W=!0,U?.kill(`SIGTERM`),(await V?.nodeChildProcess.catch(()=>void 0))?.kill(`SIGTERM`),H&&H.kill(`SIGTERM`),await K.release()}}async function k({interactive:e,takeoverApproved:t,...n}){try{return await i(n)}catch(o){if(!(o instanceof r)||!e)throw o;if(!t){let e=await _.confirm({initialValue:!1,message:`PostgreSQL is already running for this project (PID ${o.pid}). Stop it and start here?`});if(_.isCancel(e)||!e){_.cancel(`Keeping the existing PostgreSQL process.`);return}}return await a(o),i(n)}}function A(e){return(e.database?.dialect??`postgres`)===`postgres`}function re(e,t,n){return[`exec`,`tauri`,...e===`desktop`?[]:[e],`dev`,`--config`,JSON.stringify({build:{beforeDevCommand:``}}),...n===void 0?[]:[`--host=${n}`],...t===void 0?[]:[t]]}function ie(e){return e===`desktop`?v.platform===`win32`?`windows`:v.platform:e}function j({host:e,port:t}){return[`dev`,...e===void 0?[]:[`--host`,e===!0?`0.0.0.0`:e],...t===void 0?[]:[`--port`,String(t)]]}function ae({host:e,port:t}){return[`run`,...t===void 0?[]:[`--app-port`,String(t)],`react-router`,...j({host:e,port:void 0})]}function M(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}export{x as devPlatforms,S as resolveDevPlatforms,O as runDevServer};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region recipes/apply.d.ts
|
|
2
|
+
type ApplyRecipeOptions = {
|
|
3
|
+
cwd?: string;
|
|
4
|
+
fetch?: boolean;
|
|
5
|
+
name: string;
|
|
6
|
+
remote?: string;
|
|
7
|
+
target?: string;
|
|
8
|
+
};
|
|
9
|
+
type AppliedRecipe = {
|
|
10
|
+
created: string[];
|
|
11
|
+
instructions: string;
|
|
12
|
+
name: string;
|
|
13
|
+
ref: string;
|
|
14
|
+
unchanged: string[];
|
|
15
|
+
updated: string[];
|
|
16
|
+
};
|
|
17
|
+
declare function applyRecipe({
|
|
18
|
+
cwd,
|
|
19
|
+
fetch,
|
|
20
|
+
name,
|
|
21
|
+
remote,
|
|
22
|
+
target
|
|
23
|
+
}: ApplyRecipeOptions): AppliedRecipe;
|
|
24
|
+
declare function printAppliedRecipe(result: AppliedRecipe): void;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { AppliedRecipe, ApplyRecipeOptions, applyRecipe, printAppliedRecipe };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{parseRecipeManifest as e,validateRecipeName as t}from"./manifest.js";import{listGitFiles as n,readGitBuffer as r,readGitText as i,resolveRecipeSource as a}from"./source.js";import{dirname as o,isAbsolute as s,join as c,posix as l}from"node:path";import{existsSync as u,lstatSync as d,mkdirSync as f,readFileSync as p,writeFileSync as m}from"node:fs";import{parse as h,stringify as g}from"yaml";function _({cwd:s=process.cwd(),fetch:c=!0,name:l,remote:d=`template`,target:p}){t(l);let{projectRoot:h,ref:_,repositoryRoot:v}=a({cwd:s,fetch:c,remote:d,target:p}),b=`recipes/${l}`,C=`${b}/recipe.yaml`,E=e(i(v,_,C),C),D=i(v,_,`${b}/RECIPE.md`),O=n(v,_,`${b}/.agents`),k=new Map,A=[],j=[],M=[];for(let e of O){let t=e.slice(`${b}/`.length);x(t,`Recipe asset ${e}`),k.set(t,r(v,_,e))}let N=new Map;for(let[e,t]of k){let n=w(S(h,e));if(n===void 0)N.set(e,t),A.push(e);else if(n.equals(t))j.push(e);else throw Error(`Recipe ${l} cannot replace modified ${e}. Reconcile that agent asset manually.`)}let P=new Map;for(let e of E.routes){if(x(e.router,`Recipe route router`),x(e.path,`Recipe route path`),k.has(e.router))throw Error(`Recipe cannot replace its destination router ${e.router}.`);if(!k.has(e.path)&&!u(S(h,e.path)))throw Error(`Recipe route target ${e.path} does not exist.`);let t=P.get(e.router)??y(T(S(h,e.router),e.router),e.router);P.set(e.router,t);let n=t.routes.find(t=>t.path===e.path);if(n){if(n.when!==e.when)throw Error(`Recipe ${l} route ${e.path} conflicts with the existing trigger in ${e.router}.`);continue}t.routes.push({path:e.path,when:e.when})}for(let[e,t]of P){t.routes.sort((e,t)=>e.path<t.path?-1:+(e.path>t.path));let n=T(S(h,e),e),r=g(t,{lineWidth:0});r===n?j.push(e):(N.set(e,r),M.push(e))}for(let[e,t]of N){let n=S(h,e);f(o(n),{recursive:!0}),m(n,t)}return{created:A.sort(),instructions:D,name:l,ref:_,unchanged:[...new Set(j)].sort(),updated:M.sort()}}function v(e){console.log(`Prepared Coreframe recipe ${e.name} from ${e.ref}.`);for(let t of e.created)console.log(`created: ${t}`);for(let t of e.updated)console.log(`updated: ${t}`);for(let t of e.unchanged)console.log(`unchanged: ${t}`);console.log(`\nContinue by following ${e.ref}:recipes/${e.name}/RECIPE.md:\n`),console.log(e.instructions.trimEnd())}function y(e,t){let n=b(e,t);if(!E(n)||!D(n,[`routes`,`rules`])||!Array.isArray(n.rules)||!n.rules.every(O)||!Array.isArray(n.routes))throw Error(`${t} must contain only string rules and a routes array.`);let r=n.routes.map((e,n)=>{if(!E(e)||!D(e,[`path`,`when`])||!O(e.path)||!O(e.when))throw Error(`${t} route ${n+1} must contain path and when strings.`);return{path:e.path,when:e.when}}),i=r.map(e=>e.path);if(new Set(i).size!==i.length)throw Error(`${t} contains duplicate route paths.`);return{rules:n.rules,routes:r}}function b(e,t){try{return h(e)}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}}function x(e,t){if(!e.startsWith(`.agents/`)||s(e)||e.includes(`\\`)||l.normalize(e)!==e)throw Error(`${t} must be a normalized project-relative path beneath .agents/.`)}function S(e,t){x(t,`Recipe destination`);let n=c(e,t),r=e;for(let e of t.split(`/`))if(r=c(r,e),u(r)&&d(r).isSymbolicLink())throw Error(`Recipe destination ${t} crosses symbolic link ${r}.`);return n}function C(e){return w(e)?.toString(`utf8`)}function w(e){try{return p(e)}catch(e){if(k(e)&&e.code===`ENOENT`)return;throw e}}function T(e,t){let n=C(e);if(n===void 0)throw Error(`Required file ${t} does not exist.`);return n}function E(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function D(e,t){let n=Object.keys(e).sort();return n.length===t.length&&n.every((e,n)=>e===t[n])}function O(e){return typeof e==`string`&&e.length>0}function k(e){return e instanceof Error&&`code`in e}export{_ as applyRecipe,v as printAppliedRecipe};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { RecipeSourceOptions } from "./source.js";
|
|
2
|
+
|
|
3
|
+
//#region recipes/list.d.ts
|
|
4
|
+
type RecipeCatalog = {
|
|
5
|
+
recipes: Array<{
|
|
6
|
+
description: string;
|
|
7
|
+
name: string;
|
|
8
|
+
}>;
|
|
9
|
+
ref: string;
|
|
10
|
+
};
|
|
11
|
+
declare function listRecipes(options?: RecipeSourceOptions): RecipeCatalog;
|
|
12
|
+
declare function printRecipeCatalog(catalog: RecipeCatalog): void;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { RecipeCatalog, listRecipes, printRecipeCatalog };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{parseRecipeManifest as e,validateRecipeName as t}from"./manifest.js";import{listGitFiles as n,readGitText as r,resolveRecipeSource as i}from"./source.js";function a(a={}){let{ref:o,repositoryRoot:s}=i(a),c=n(s,o,`recipes`).filter(e=>/^recipes\/[^/]+\/recipe\.yaml$/u.test(e)).map(n=>{let i=n.split(`/`)[1];return t(i),{description:e(r(s,o,n),n).description,name:i}});return c.sort((e,t)=>e.name.localeCompare(t.name)),{recipes:c,ref:o}}function o(e){console.log(`Coreframe recipes at ${e.ref}:`);for(let t of e.recipes)console.log(`${t.name} — ${t.description}`)}export{a as listRecipes,o as printRecipeCatalog};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region recipes/manifest.d.ts
|
|
2
|
+
type RecipeRoute = {
|
|
3
|
+
path: string;
|
|
4
|
+
router: string;
|
|
5
|
+
when: string;
|
|
6
|
+
};
|
|
7
|
+
type RecipeManifest = {
|
|
8
|
+
description: string;
|
|
9
|
+
routes: RecipeRoute[];
|
|
10
|
+
};
|
|
11
|
+
declare function parseRecipeManifest(contents: string, path: string): RecipeManifest;
|
|
12
|
+
declare function validateRecipeName(name: string): string;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { RecipeManifest, RecipeRoute, parseRecipeManifest, validateRecipeName };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{parse as e}from"yaml";const t=/^[a-z0-9]+(?:-[a-z0-9]+)*$/u;function n(e,t){let n=i(e,t);if(!a(n)||!o(n,[`description`,`routes`])||!s(n.description)||!Array.isArray(n.routes))throw Error(`${t} must contain only a description string and routes array.`);let r=n.routes.map((e,n)=>{if(!a(e)||!o(e,[`path`,`router`,`when`])||!s(e.path)||!s(e.router)||!s(e.when))throw Error(`${t} route ${n+1} must contain router, path, and when strings.`);return{path:e.path,router:e.router,when:e.when}}),c=r.map(e=>`${e.router}\0${e.path}`);if(new Set(c).size!==c.length)throw Error(`${t} contains a duplicate router and path pair.`);return{description:n.description,routes:r}}function r(e){if(!t.test(e))throw Error(`Recipe names use lowercase letters, numbers, and single hyphens.`);return e}function i(t,n){try{return e(t)}catch(e){throw Error(`Could not parse ${n}.`,{cause:e})}}function a(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function o(e,t){let n=Object.keys(e).sort();return n.length===t.length&&n.every((e,n)=>e===t[n])}function s(e){return typeof e==`string`&&e.length>0}export{n as parseRecipeManifest,r as validateRecipeName};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region recipes/source.d.ts
|
|
2
|
+
type RecipeSourceOptions = {
|
|
3
|
+
cwd?: string;
|
|
4
|
+
fetch?: boolean;
|
|
5
|
+
remote?: string;
|
|
6
|
+
target?: string;
|
|
7
|
+
};
|
|
8
|
+
declare function resolveRecipeSource({
|
|
9
|
+
cwd,
|
|
10
|
+
fetch,
|
|
11
|
+
remote,
|
|
12
|
+
target
|
|
13
|
+
}?: RecipeSourceOptions): {
|
|
14
|
+
projectRoot: string;
|
|
15
|
+
ref: string;
|
|
16
|
+
repositoryRoot: string;
|
|
17
|
+
};
|
|
18
|
+
declare function readGitText(repositoryRoot: string, ref: string, path: string): string;
|
|
19
|
+
declare function readGitBuffer(repositoryRoot: string, ref: string, path: string): NonSharedBuffer;
|
|
20
|
+
declare function listGitFiles(repositoryRoot: string, ref: string, path: string): string[];
|
|
21
|
+
//#endregion
|
|
22
|
+
export { RecipeSourceOptions, listGitFiles, readGitBuffer, readGitText, resolveRecipeSource };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ensureTemplateRemote as e}from"../upgrade/ensure-template-remote.js";import{coreframeGitRef as t}from"../upgrade/template-ref.js";import{dirname as n,join as r,resolve as i}from"node:path";import{readFileSync as a}from"node:fs";import{spawnSync as o}from"node:child_process";function s({cwd:n=process.cwd(),fetch:r=!0,remote:i=`template`,target:a}={}){let o=d(n),s=h(o,[`rev-parse`,`--show-toplevel`]),c=t(a??f(o));return e({cwd:s,fetch:r,remote:i}),{projectRoot:o,ref:c,repositoryRoot:s}}function c(e,t,n){return l(e,t,n).toString(`utf8`)}function l(e,t,n){let r=`${t}:${n}`,i=o(`git`,[`show`,r],{cwd:e,encoding:`buffer`});if(i.status!==0)throw Error(`Could not read ${r}. ${g([`show`,r],i)}`);return i.stdout}function u(e,t,n){let r=o(`git`,[`ls-tree`,`-r`,`--name-only`,`-z`,t,`--`,n],{cwd:e,encoding:`buffer`});if(r.status!==0)throw Error(g([`ls-tree`,t,n],r));return r.stdout.toString(`utf8`).split(`\0`).filter(Boolean)}function d(e){let t=i(e);for(;;){let e=r(t,`package.json`),i=m(e);if(i!==void 0&&p(i,e).engines?.coreframe)return t;let a=n(t);if(a===t)throw Error(`Could not find a package.json with engines.coreframe.`);t=a}}function f(e){let t=r(e,`package.json`),n=m(t);if(n===void 0)throw Error(`Required file package.json does not exist.`);let i=p(n,t).engines?.coreframe;if(!i)throw Error(`package.json must declare an exact engines.coreframe recipe baseline.`);return i}function p(e,t){try{return JSON.parse(e)}catch(e){throw Error(`Could not parse ${t}.`,{cause:e})}}function m(e){try{return a(e,`utf8`)}catch(e){if(_(e)&&e.code===`ENOENT`)return;throw e}}function h(e,t){let n=o(`git`,t,{cwd:e,encoding:`utf8`});if(n.status!==0)throw Error(g(t,n));return n.stdout.trim()}function g(e,t){let n=t.stderr.toString(`utf8`).trim()||t.stdout.toString(`utf8`).trim();return`Git command failed: git ${e.join(` `)}${n?`\n${n}`:``}`}function _(e){return e instanceof Error&&`code`in e}export{u as listGitFiles,l as readGitBuffer,c as readGitText,s as resolveRecipeSource};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Writable } from "node:stream";
|
|
2
|
+
|
|
3
|
+
//#region tauri-dev-output.d.ts
|
|
4
|
+
type TauriDevOutput = {
|
|
5
|
+
close(): Promise<void>;
|
|
6
|
+
consume(lines: AsyncIterable<string>): Promise<void>;
|
|
7
|
+
logFile: string;
|
|
8
|
+
reportFailure(): Promise<void>;
|
|
9
|
+
};
|
|
10
|
+
type CreateTauriDevOutputOptions = {
|
|
11
|
+
output: Writable;
|
|
12
|
+
temporaryDirectory?: string;
|
|
13
|
+
};
|
|
14
|
+
declare function createTauriDevOutput({
|
|
15
|
+
output,
|
|
16
|
+
temporaryDirectory
|
|
17
|
+
}: CreateTauriDevOutputOptions): Promise<TauriDevOutput>;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { TauriDevOutput, createTauriDevOutput };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{mkdtemp as e}from"node:fs/promises";import t from"node:path";import{createWriteStream as n}from"node:fs";import{tmpdir as r}from"node:os";import{stripVTControlCharacters as i}from"node:util";import{once as a}from"node:events";import{finished as o}from"node:stream/promises";async function s({output:i,temporaryDirectory:o=r()}){let s=await e(t.join(o,`coreframe-ios-dev-`)),l=t.join(s,`tauri.log`),u=n(l,{flags:`wx`,mode:384});return await a(u,`open`),new c(l,u,i)}var c=class{logFile;closed=!1;failureLines=[];log;output;runtime=!1;showInstalledBundleId=!1;constructor(e,t,n){this.logFile=e,this.log=t,this.output=n}async consume(e){try{for await(let t of e)await d(this.log,`${t}\n`),this.rememberFailureLine(t),this.shouldShow(t)&&await d(this.output,`${t}\n`)}catch{}}async reportFailure(){await d(this.output,`iOS development failed. Recent diagnostic output:
|
|
2
|
+
`);for(let e of this.failureLines)await d(this.output,`${e}\n`);await d(this.output,`Full iOS log: ${this.logFile}\n`)}async close(){this.closed||(this.closed=!0,this.log.end(),await o(this.log))}shouldShow(e){let t=i(e).trim();if(t===`Building app...`)return this.runtime=!1,!0;if(l(t))return!1;if(t.startsWith(`Launched application with `))return this.runtime=!0,!0;if(this.runtime)return!0;if(t===`App installed:`)return this.showInstalledBundleId=!0,!0;if(this.showInstalledBundleId){if(t.length===0)return!1;if(this.showInstalledBundleId=!1,t.startsWith(`• bundleID:`))return!0}return/^(Archiving app|Exporting app|Extracting IPA|Deploying app to device|Pairing with device)\.\.\.$/u.test(t)||/^\*\* BUILD (?:SUCCEEDED|FAILED) \*\*$/u.test(t)||/^(?:Compiling|Checking|Finished)\b/u.test(t)||/^(?:Warn|Error)\b/u.test(t)||/(?:^|:\d+:\d+: )(?:warning|error)(?:\[[^\]]+\])?:/iu.test(t)||/^(?:fatal:|thread .+ panicked|Failed to |No device found\.|The following build commands failed:|command \[.+\] exited)/iu.test(t)||/^Info Watching\b/u.test(t)||/^note: run with RUST_BACKTRACE=/u.test(t)}rememberFailureLine(e){u(i(e).trim())||(this.failureLines.push(e),this.failureLines.length>40&&this.failureLines.shift())}};function l(e){return e.startsWith(`--- xcodebuild: WARNING: Using the first of multiple matching destinations:`)||/^Failed to load provisioning param(?:e)?ter list due to error:/u.test(e)||e==="`devicectl manage create` may support a reduced set of arguments."||/(?:^|\/)idevicesyslog$/u.test(e)}function u(e){return e.length===0||e.startsWith(`export `)||e.startsWith(`inflating:`)||e.startsWith(`Archive:`)||e.startsWith(`cd `)||e.startsWith(`/bin/sh -c `)||e.startsWith(`Command line invocation:`)||e.startsWith(`Build settings from command line:`)}async function d(e,t){e.write(t)||await a(e,`drain`)}export{s as createTauriDevOutput};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
//#region upgrade/ensure-template-remote.d.ts
|
|
2
2
|
type EnsureTemplateRemoteOptions = {
|
|
3
|
+
cwd: string;
|
|
3
4
|
fetch: boolean;
|
|
4
5
|
remote: string;
|
|
5
6
|
};
|
|
6
7
|
declare function ensureTemplateRemote({
|
|
8
|
+
cwd,
|
|
7
9
|
fetch,
|
|
8
10
|
remote
|
|
9
11
|
}?: Partial<EnsureTemplateRemoteOptions>): void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{spawnSync as e}from"node:child_process";const t=`https://github.com/airlock-labs/coreframe.git`;function n(t){return e(`git`,t,{encoding:`utf8`})}function r(e){let
|
|
2
|
+
import{spawnSync as e}from"node:child_process";const t=`https://github.com/airlock-labs/coreframe.git`;function n(t,n){return e(`git`,t,{cwd:n,encoding:`utf8`})}function r(e,t){let r=n(e,t);if(r.status!==0){let t=r.stderr.trim()||r.stdout.trim();throw Error(`Git command failed: git ${e.join(` `)}${t?`\n${t}`:``}`)}return r.stdout}function i(e,t){let r=n([`remote`,`get-url`,e],t);if(r.status===2)return null;if(r.status!==0){let t=r.stderr.trim()||r.stdout.trim();throw Error(`Could not inspect remote ${e}.${t?`\n${t}`:``}`)}return r.stdout.trim()}function a({cwd:e=process.cwd(),fetch:n=!0,remote:a=`template`}={}){if(a.length===0)throw Error(`Remote name must not be empty.`);r([`rev-parse`,`--show-toplevel`],e);let o=i(a,e);if(o===null)r([`remote`,`add`,a,t],e),console.log(`Added ${a} remote: ${t}`);else if(o===t)console.log(`${a} remote already points at ${t}`);else throw Error(`${a} remote points at ${o}, not ${t}.\nChoose the intended template source before continuing, then update or rename the remote manually.`);n&&(r([`fetch`,a,`--tags`,`--prune`],e),console.log(`Fetched ${a}.`))}export{a as ensureTemplateRemote};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coreframe/scripts",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.34",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/airlock-labs/coreframe.git",
|
|
@@ -28,7 +28,8 @@
|
|
|
28
28
|
"local-postgres": "0.3.0",
|
|
29
29
|
"nano-spawn": "^2.1.0",
|
|
30
30
|
"procband": "^0.3.7",
|
|
31
|
-
"tinyglobby": "^0.2.17"
|
|
31
|
+
"tinyglobby": "^0.2.17",
|
|
32
|
+
"yaml": "^2.9.0"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|
|
34
35
|
"@types/node": "^26.1.0",
|