@pwfabric/cli 0.0.0-stage → 1.0.0-rc.0

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.
Files changed (171) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +122 -2
  3. package/dist/args.d.ts +12 -0
  4. package/dist/args.d.ts.map +1 -0
  5. package/dist/args.js +43 -0
  6. package/dist/args.js.map +1 -0
  7. package/dist/bin.d.ts +3 -0
  8. package/dist/bin.d.ts.map +1 -0
  9. package/dist/bin.js +10 -0
  10. package/dist/bin.js.map +1 -0
  11. package/dist/commands/add.d.ts +4 -0
  12. package/dist/commands/add.d.ts.map +1 -0
  13. package/dist/commands/add.js +56 -0
  14. package/dist/commands/add.js.map +1 -0
  15. package/dist/commands/build.d.ts +4 -0
  16. package/dist/commands/build.d.ts.map +1 -0
  17. package/dist/commands/build.js +55 -0
  18. package/dist/commands/build.js.map +1 -0
  19. package/dist/commands/create.d.ts +10 -0
  20. package/dist/commands/create.d.ts.map +1 -0
  21. package/dist/commands/create.js +119 -0
  22. package/dist/commands/create.js.map +1 -0
  23. package/dist/commands/dev.d.ts +13 -0
  24. package/dist/commands/dev.d.ts.map +1 -0
  25. package/dist/commands/dev.js +107 -0
  26. package/dist/commands/dev.js.map +1 -0
  27. package/dist/commands/lib/flags.d.ts +11 -0
  28. package/dist/commands/lib/flags.d.ts.map +1 -0
  29. package/dist/commands/lib/flags.js +33 -0
  30. package/dist/commands/lib/flags.js.map +1 -0
  31. package/dist/commands/lib/identity.d.ts +39 -0
  32. package/dist/commands/lib/identity.d.ts.map +1 -0
  33. package/dist/commands/lib/identity.js +120 -0
  34. package/dist/commands/lib/identity.js.map +1 -0
  35. package/dist/commands/lib/project.d.ts +35 -0
  36. package/dist/commands/lib/project.d.ts.map +1 -0
  37. package/dist/commands/lib/project.js +78 -0
  38. package/dist/commands/lib/project.js.map +1 -0
  39. package/dist/commands/lib/report.d.ts +16 -0
  40. package/dist/commands/lib/report.d.ts.map +1 -0
  41. package/dist/commands/lib/report.js +75 -0
  42. package/dist/commands/lib/report.js.map +1 -0
  43. package/dist/commands/lib/starter.d.ts +42 -0
  44. package/dist/commands/lib/starter.d.ts.map +1 -0
  45. package/dist/commands/lib/starter.js +136 -0
  46. package/dist/commands/lib/starter.js.map +1 -0
  47. package/dist/commands/lib/static-server.d.ts +46 -0
  48. package/dist/commands/lib/static-server.d.ts.map +1 -0
  49. package/dist/commands/lib/static-server.js +173 -0
  50. package/dist/commands/lib/static-server.js.map +1 -0
  51. package/dist/commands/pack.d.ts +6 -0
  52. package/dist/commands/pack.d.ts.map +1 -0
  53. package/dist/commands/pack.js +56 -0
  54. package/dist/commands/pack.js.map +1 -0
  55. package/dist/commands/registry.d.ts +8 -0
  56. package/dist/commands/registry.d.ts.map +1 -0
  57. package/dist/commands/registry.js +16 -0
  58. package/dist/commands/registry.js.map +1 -0
  59. package/dist/commands/run.d.ts +15 -0
  60. package/dist/commands/run.d.ts.map +1 -0
  61. package/dist/commands/run.js +79 -0
  62. package/dist/commands/run.js.map +1 -0
  63. package/dist/commands/types.d.ts +35 -0
  64. package/dist/commands/types.d.ts.map +1 -0
  65. package/dist/commands/types.js +10 -0
  66. package/dist/commands/types.js.map +1 -0
  67. package/dist/commands/validate.d.ts +7 -0
  68. package/dist/commands/validate.d.ts.map +1 -0
  69. package/dist/commands/validate.js +33 -0
  70. package/dist/commands/validate.js.map +1 -0
  71. package/dist/dev/assemble.d.ts +48 -0
  72. package/dist/dev/assemble.d.ts.map +1 -0
  73. package/dist/dev/assemble.js +339 -0
  74. package/dist/dev/assemble.js.map +1 -0
  75. package/dist/dev/compile.d.ts +55 -0
  76. package/dist/dev/compile.d.ts.map +1 -0
  77. package/dist/dev/compile.js +215 -0
  78. package/dist/dev/compile.js.map +1 -0
  79. package/dist/dev/csp.d.ts +68 -0
  80. package/dist/dev/csp.d.ts.map +1 -0
  81. package/dist/dev/csp.js +260 -0
  82. package/dist/dev/csp.js.map +1 -0
  83. package/dist/dev/diagnostics.d.ts +22 -0
  84. package/dist/dev/diagnostics.d.ts.map +1 -0
  85. package/dist/dev/diagnostics.js +22 -0
  86. package/dist/dev/diagnostics.js.map +1 -0
  87. package/dist/dev/envelope.d.ts +93 -0
  88. package/dist/dev/envelope.d.ts.map +1 -0
  89. package/dist/dev/envelope.js +154 -0
  90. package/dist/dev/envelope.js.map +1 -0
  91. package/dist/dev/media.d.ts +54 -0
  92. package/dist/dev/media.d.ts.map +1 -0
  93. package/dist/dev/media.js +128 -0
  94. package/dist/dev/media.js.map +1 -0
  95. package/dist/dev/needs-host.d.ts +3 -0
  96. package/dist/dev/needs-host.d.ts.map +1 -0
  97. package/dist/dev/needs-host.js +32 -0
  98. package/dist/dev/needs-host.js.map +1 -0
  99. package/dist/dev/output.d.ts +10 -0
  100. package/dist/dev/output.d.ts.map +1 -0
  101. package/dist/dev/output.js +32 -0
  102. package/dist/dev/output.js.map +1 -0
  103. package/dist/dev/overlay.d.ts +22 -0
  104. package/dist/dev/overlay.d.ts.map +1 -0
  105. package/dist/dev/overlay.js +59 -0
  106. package/dist/dev/overlay.js.map +1 -0
  107. package/dist/dev/server.d.ts +28 -0
  108. package/dist/dev/server.d.ts.map +1 -0
  109. package/dist/dev/server.js +264 -0
  110. package/dist/dev/server.js.map +1 -0
  111. package/dist/dev/shell.d.ts +83 -0
  112. package/dist/dev/shell.d.ts.map +1 -0
  113. package/dist/dev/shell.js +244 -0
  114. package/dist/dev/shell.js.map +1 -0
  115. package/dist/dev/sources.d.ts +46 -0
  116. package/dist/dev/sources.d.ts.map +1 -0
  117. package/dist/dev/sources.js +165 -0
  118. package/dist/dev/sources.js.map +1 -0
  119. package/dist/dev/theme.d.ts +52 -0
  120. package/dist/dev/theme.d.ts.map +1 -0
  121. package/dist/dev/theme.js +185 -0
  122. package/dist/dev/theme.js.map +1 -0
  123. package/dist/dev/types.d.ts +41 -0
  124. package/dist/dev/types.d.ts.map +1 -0
  125. package/dist/dev/types.js +11 -0
  126. package/dist/dev/types.js.map +1 -0
  127. package/dist/dev/watcher.d.ts +30 -0
  128. package/dist/dev/watcher.d.ts.map +1 -0
  129. package/dist/dev/watcher.js +150 -0
  130. package/dist/dev/watcher.js.map +1 -0
  131. package/dist/host/definitions.d.ts +62 -0
  132. package/dist/host/definitions.d.ts.map +1 -0
  133. package/dist/host/definitions.js +136 -0
  134. package/dist/host/definitions.js.map +1 -0
  135. package/dist/host/http.d.ts +40 -0
  136. package/dist/host/http.d.ts.map +1 -0
  137. package/dist/host/http.js +156 -0
  138. package/dist/host/http.js.map +1 -0
  139. package/dist/host/local-host.d.ts +60 -0
  140. package/dist/host/local-host.d.ts.map +1 -0
  141. package/dist/host/local-host.js +420 -0
  142. package/dist/host/local-host.js.map +1 -0
  143. package/dist/host/oidc.d.ts +47 -0
  144. package/dist/host/oidc.d.ts.map +1 -0
  145. package/dist/host/oidc.js +192 -0
  146. package/dist/host/oidc.js.map +1 -0
  147. package/dist/host/query.d.ts +36 -0
  148. package/dist/host/query.d.ts.map +1 -0
  149. package/dist/host/query.js +158 -0
  150. package/dist/host/query.js.map +1 -0
  151. package/dist/host/receipts.d.ts +26 -0
  152. package/dist/host/receipts.d.ts.map +1 -0
  153. package/dist/host/receipts.js +72 -0
  154. package/dist/host/receipts.js.map +1 -0
  155. package/dist/host/records.d.ts +74 -0
  156. package/dist/host/records.d.ts.map +1 -0
  157. package/dist/host/records.js +229 -0
  158. package/dist/host/records.js.map +1 -0
  159. package/dist/host/tokens.d.ts +29 -0
  160. package/dist/host/tokens.d.ts.map +1 -0
  161. package/dist/host/tokens.js +52 -0
  162. package/dist/host/tokens.js.map +1 -0
  163. package/dist/host/types.d.ts +33 -0
  164. package/dist/host/types.d.ts.map +1 -0
  165. package/dist/host/types.js +11 -0
  166. package/dist/host/types.js.map +1 -0
  167. package/dist/index.d.ts +17 -0
  168. package/dist/index.d.ts.map +1 -0
  169. package/dist/index.js +41 -0
  170. package/dist/index.js.map +1 -0
  171. package/package.json +65 -3
@@ -0,0 +1,119 @@
1
+ /**
2
+ * `pwf create <name>` — a new app folder standing on a foundation pack.
3
+ */
4
+ import { mkdir, readdir, writeFile } from 'node:fs/promises';
5
+ import { dirname, isAbsolute, join, relative } from 'node:path';
6
+ import { hashPack, packContent, validatePack } from '@pwfabric/pack';
7
+ import { boolFlag, guard, stringFlag, UsageError } from './lib/flags.js';
8
+ import { cacheDir, cacheRelDir, readPackSource, resolveFrom, writePackFolder, ATOMS_README } from './lib/project.js';
9
+ import { caretRange, engineRange, engineVersion, formatIdentity, formatJson } from './lib/identity.js';
10
+ import { printIssues } from './lib/report.js';
11
+ import { ATOMS_README_TEXT, catalogOf, GITIGNORE_TEXT, starterAppearance, starterBlocks, starterNavigation, starterPlan, starterReceipt, starterTheme, titleOf, } from './lib/starter.js';
12
+ /** Environment variable naming the foundation pack when `--foundation` is not given. */
13
+ export const FOUNDATION_ENV = 'PWF_FOUNDATION';
14
+ const NAME = /^[a-z0-9][a-z0-9-]*$/;
15
+ const NO_FOUNDATION = [
16
+ 'pwf create: no foundation pack given.',
17
+ 'Every app stands on a foundation pack (its blocks, themes and shells). The',
18
+ 'foundation pack is not published to a registry yet, so point pwf at a copy:',
19
+ ' pwf create <name> --foundation <folder or .pwpack>',
20
+ `or set ${FOUNDATION_ENV} to that path once for every create.`,
21
+ ];
22
+ async function isNonEmptyDir(dir) {
23
+ const entries = await readdir(dir).catch(() => null);
24
+ return entries !== null && entries.length > 0;
25
+ }
26
+ export async function runCreate(args, io, options = {}) {
27
+ const name = args.positionals[0];
28
+ if (name === undefined)
29
+ throw new UsageError('missing <name>');
30
+ if (!NAME.test(name))
31
+ throw new UsageError(`"${name}" is not a valid name: use lower-case letters, digits and hyphens`);
32
+ const target = resolveFrom(io.cwd, stringFlag(args, 'dir') ?? name);
33
+ const force = boolFlag(args, 'force');
34
+ const foundationPath = stringFlag(args, 'foundation') ?? io.env[FOUNDATION_ENV];
35
+ if (!foundationPath) {
36
+ for (const line of NO_FOUNDATION)
37
+ io.err(line);
38
+ return 1;
39
+ }
40
+ if (!force && (await isNonEmptyDir(target))) {
41
+ io.err(`pwf create: ${target} is not empty; choose another --dir or pass --force to write into it`);
42
+ return 1;
43
+ }
44
+ const foundationAbs = resolveFrom(io.cwd, foundationPath);
45
+ const foundation = await readPackSource(foundationAbs);
46
+ const checked = validatePack(foundation);
47
+ if (!checked.ok || !checked.identity) {
48
+ io.err(`pwf create: the foundation pack at ${foundationAbs} is not valid`);
49
+ printIssues(io, checked.issues.filter((i) => i.severity === 'error'));
50
+ return 1;
51
+ }
52
+ const { id: foundationId, version: foundationVersion } = checked.identity;
53
+ const catalog = catalogOf(foundation, checked);
54
+ const title = titleOf(name);
55
+ const blocks = starterBlocks(catalog, title);
56
+ if (blocks.length === 0) {
57
+ io.err(`pwf create: ${foundationId}@${foundationVersion} has no heading, text or button block to start a page with`);
58
+ return 1;
59
+ }
60
+ const theme = starterTheme(catalog);
61
+ // What is cached and pinned is the pack content: a foundation read from its
62
+ // source folder brings its package.json, scripts and tests, none of which
63
+ // the app stands on.
64
+ const foundationContent = packContent(foundation);
65
+ const foundationHash = hashPack(foundationContent);
66
+ const identity = {
67
+ id: `@pwpack/local/${name}`,
68
+ version: '0.1.0',
69
+ formatVersion: '1.0',
70
+ engines: { pwfabric: engineRange(options.engineVersion ?? engineVersion()) },
71
+ requires: [{ id: foundationId, range: caretRange(foundationVersion) }],
72
+ license: { fork: true, redistribute: true },
73
+ app: { entry: 'home', surfaceOrder: ['home'] },
74
+ packs: [{ id: foundationId, version: foundationVersion, hash: foundationHash }],
75
+ };
76
+ const files = {
77
+ 'pwpack.json': formatIdentity(identity),
78
+ 'app/plan.json': formatJson(starterPlan(name, title, blocks, foundationId, theme)),
79
+ 'app/definitions/appearance.json': formatJson(starterAppearance(theme)),
80
+ 'app/definitions/navigation.json': formatJson(starterNavigation()),
81
+ 'app/surfaces/home.receipt.json': formatJson(starterReceipt(blocks)),
82
+ [ATOMS_README]: ATOMS_README_TEXT,
83
+ '.gitignore': GITIGNORE_TEXT,
84
+ };
85
+ for (const [path, text] of Object.entries(files)) {
86
+ const abs = join(target, ...path.split('/'));
87
+ await mkdir(dirname(abs), { recursive: true });
88
+ await writeFile(abs, text);
89
+ }
90
+ await writePackFolder(cacheDir(target, foundationId, foundationVersion), foundationContent);
91
+ const rel = relative(io.cwd, target);
92
+ const shown = rel === '' ? '.' : rel.startsWith('..') || isAbsolute(rel) ? target : rel;
93
+ io.out(`Created ${identity.id} in ${target}`);
94
+ io.out(` foundation ${foundationId}@${foundationVersion} (${foundationHash})`);
95
+ io.out(` cached in ${cacheRelDir(foundationId, foundationVersion)}`);
96
+ io.out(` home page ${blocks.map((b) => b.type).join(', ')}${theme ? `; theme ${theme}` : ''}`);
97
+ io.out('');
98
+ io.out('Next:');
99
+ io.out(` cd ${shown}`);
100
+ io.out(' pwf dev # serve it and rebuild on change');
101
+ io.out(' pwf validate # check the folder');
102
+ io.out(' pwf pack # write the .pwpack');
103
+ return 0;
104
+ }
105
+ export const create = {
106
+ name: 'create',
107
+ summary: 'Create a new app folder standing on a foundation pack',
108
+ usage: `pwf create <name> [--dir <path>] [--foundation <folder|.pwpack>] [--force]
109
+
110
+ <name> lower-case letters, digits and hyphens; the app id is @pwpack/local/<name>
111
+ --dir <path> where to write it (default ./<name>)
112
+ --foundation the foundation pack to stand on (default: $${FOUNDATION_ENV})
113
+ --force write into a folder that is not empty
114
+
115
+ The foundation is copied into .pwf/packs/<id>@<version>/ and pinned in
116
+ pwpack.json by content hash, so dev and run work offline.`,
117
+ run: (args, io) => guard('create', io, () => runCreate(args, io)),
118
+ };
119
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { type DevServerInternals } from '../dev/server.js';
2
+ import type { Command, CommandIO, ParsedArgs } from './types.js';
3
+ /** Resolves when the process is asked to stop (Ctrl+C or a termination signal). */
4
+ export declare function untilInterrupted(): Promise<void>;
5
+ export interface DevCommandOptions {
6
+ /** What keeps the server running; default {@link untilInterrupted}. */
7
+ readonly until?: () => Promise<void>;
8
+ /** Passed through to the server (tests turn watching off). */
9
+ readonly internals?: DevServerInternals;
10
+ }
11
+ export declare function runDev(args: ParsedArgs, io: CommandIO, options?: DevCommandOptions): Promise<number>;
12
+ export declare const devCommand: Command;
13
+ //# sourceMappingURL=dev.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAWA,OAAO,EAAgE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAExH,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEhE,mFAAmF;AACnF,wBAAgB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAUhD;AAED,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACpC,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,CAAC,EAAE,kBAAkB,CAAA;CACxC;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoE9G;AAED,eAAO,MAAM,UAAU,EAAE,OAexB,CAAA"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * `pwf dev [dir] [--port <n>] [--host <name>] [--local-host | --no-host]` —
3
+ * serves the app locally, rebuilds on every change and reloads the page. Runs
4
+ * until interrupted.
5
+ *
6
+ * This is where the dev server and the local host meet (ARCHITECTURE.md:
7
+ * `dev/` knows the host's interface only). The host is mounted under
8
+ * `/_host` when the app declares sign-in or records, or when `--local-host`
9
+ * asks for it; `--no-host` serves the pages alone.
10
+ */
11
+ import { resolve } from 'node:path';
12
+ import { createDevServer, DEFAULT_HOSTNAME, DEFAULT_PORT, HOST_PREFIX } from '../dev/server.js';
13
+ import { createLocalHost } from '../host/local-host.js';
14
+ /** Resolves when the process is asked to stop (Ctrl+C or a termination signal). */
15
+ export function untilInterrupted() {
16
+ return new Promise((done) => {
17
+ const stop = () => {
18
+ process.off('SIGINT', stop);
19
+ process.off('SIGTERM', stop);
20
+ done();
21
+ };
22
+ process.once('SIGINT', stop);
23
+ process.once('SIGTERM', stop);
24
+ });
25
+ }
26
+ export async function runDev(args, io, options = {}) {
27
+ const portFlag = args.flags['port'];
28
+ let port = DEFAULT_PORT;
29
+ if (portFlag !== undefined) {
30
+ const n = typeof portFlag === 'string' ? Number(portFlag) : NaN;
31
+ if (!Number.isInteger(n) || n < 0 || n > 65535) {
32
+ io.err('pwf dev: --port needs a number from 0 to 65535');
33
+ return 2;
34
+ }
35
+ port = n;
36
+ }
37
+ const hostFlag = args.flags['host'];
38
+ if (hostFlag === true || hostFlag === '') {
39
+ io.err('pwf dev: --host needs an interface name or address');
40
+ return 2;
41
+ }
42
+ const hostname = typeof hostFlag === 'string' ? hostFlag : DEFAULT_HOSTNAME;
43
+ // A switch followed by the folder (`pwf dev --no-host ./app`) is read by the
44
+ // argument parser as the switch's value; take it back as the folder.
45
+ let dirArg = args.positionals[0];
46
+ const extra = [];
47
+ const switchOn = (name) => {
48
+ const v = args.flags[name];
49
+ if (v === undefined || v === false || v === 'false')
50
+ return false;
51
+ if (typeof v === 'string' && v !== 'true') {
52
+ if (dirArg === undefined)
53
+ dirArg = v;
54
+ else
55
+ extra.push(v);
56
+ }
57
+ return true;
58
+ };
59
+ const forceHost = switchOn('local-host');
60
+ const noHost = switchOn('no-host');
61
+ if (extra.length > 0) {
62
+ io.err(`pwf dev: unexpected argument ${extra.map((e) => `"${e}"`).join(', ')}; pwf dev serves one folder`);
63
+ return 2;
64
+ }
65
+ if (forceHost && noHost) {
66
+ io.err('pwf dev: --local-host and --no-host contradict each other; pass one');
67
+ return 2;
68
+ }
69
+ const root = resolve(io.cwd, dirArg ?? '.');
70
+ // Undefined lets the server decide from the app's declarations.
71
+ const localHost = noHost ? false : forceHost ? true : undefined;
72
+ const internals = { createHost: createLocalHost, ...options.internals };
73
+ let server;
74
+ try {
75
+ server = await createDevServer({ root, port, hostname, log: io.out, ...(localHost !== undefined ? { localHost } : {}) }, internals);
76
+ }
77
+ catch (e) {
78
+ const err = e;
79
+ io.err(err.code === 'EADDRINUSE'
80
+ ? `pwf dev: port ${port} is in use; pass --port <n> (or --port 0 for any free port)`
81
+ : `pwf dev: ${err.message}`);
82
+ return 1;
83
+ }
84
+ io.out(`pwf dev: serving ${root} at ${server.url}`);
85
+ io.out('press Ctrl+C to stop');
86
+ await (options.until ?? untilInterrupted)();
87
+ await server.close();
88
+ io.out('pwf dev: stopped');
89
+ return 0;
90
+ }
91
+ export const devCommand = {
92
+ name: 'dev',
93
+ summary: 'Serve the app locally and reload it on every change',
94
+ usage: `pwf dev [dir] [--port <n>] [--host <name>] [--local-host | --no-host]
95
+
96
+ dir the app folder (default: the current folder)
97
+ --port <n> port to listen on (default ${DEFAULT_PORT}; 0 picks a free one)
98
+ --host <name> interface to bind (default ${DEFAULT_HOSTNAME})
99
+ --local-host mount the local host for sign-in and data even when the app declares neither
100
+ --no-host do not mount the local host, even when the app declares sign-in or records
101
+
102
+ The local host (under ${HOST_PREFIX}) is for development only: records live in
103
+ memory and are seeded from app/data/, the one development user signs in
104
+ with any password, and nothing survives a restart.`,
105
+ run: (args, io) => runDev(args, io),
106
+ };
107
+ //# sourceMappingURL=dev.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { CommandIO, ParsedArgs } from '../types.js';
2
+ /** Thrown for a malformed invocation; commands turn it into exit code 2. */
3
+ export declare class UsageError extends Error {
4
+ }
5
+ /** A flag that takes a value: absent → undefined, bare `--flag` → UsageError. */
6
+ export declare function stringFlag(args: ParsedArgs, name: string): string | undefined;
7
+ /** A switch: present (bare or with any value but "false") → true. */
8
+ export declare function boolFlag(args: ParsedArgs, name: string): boolean;
9
+ /** Runs a command body, turning usage errors into exit 2 and other failures into exit 1. */
10
+ export declare function guard(name: string, io: CommandIO, body: () => Promise<number>): Promise<number>;
11
+ //# sourceMappingURL=flags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../../../src/commands/lib/flags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExD,4EAA4E;AAC5E,qBAAa,UAAW,SAAQ,KAAK;CAAG;AAExC,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAK7E;AAED,qEAAqE;AACrE,wBAAgB,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAGhE;AAED,4FAA4F;AAC5F,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAYrG"}
@@ -0,0 +1,33 @@
1
+ /** Thrown for a malformed invocation; commands turn it into exit code 2. */
2
+ export class UsageError extends Error {
3
+ }
4
+ /** A flag that takes a value: absent → undefined, bare `--flag` → UsageError. */
5
+ export function stringFlag(args, name) {
6
+ const v = args.flags[name];
7
+ if (v === undefined)
8
+ return undefined;
9
+ if (v === true || v === '')
10
+ throw new UsageError(`--${name} needs a value`);
11
+ return v;
12
+ }
13
+ /** A switch: present (bare or with any value but "false") → true. */
14
+ export function boolFlag(args, name) {
15
+ const v = args.flags[name];
16
+ return v !== undefined && v !== false && v !== 'false';
17
+ }
18
+ /** Runs a command body, turning usage errors into exit 2 and other failures into exit 1. */
19
+ export async function guard(name, io, body) {
20
+ try {
21
+ return await body();
22
+ }
23
+ catch (e) {
24
+ if (e instanceof UsageError) {
25
+ io.err(`pwf ${name}: ${e.message}`);
26
+ io.err(`Run \`pwf ${name} --help\` for usage.`);
27
+ return 2;
28
+ }
29
+ io.err(`pwf ${name}: ${e.message}`);
30
+ return 1;
31
+ }
32
+ }
33
+ //# sourceMappingURL=flags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flags.js","sourceRoot":"","sources":["../../../src/commands/lib/flags.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,MAAM,OAAO,UAAW,SAAQ,KAAK;CAAG;AAExC,iFAAiF;AACjF,MAAM,UAAU,UAAU,CAAC,IAAgB,EAAE,IAAY;IACvD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC1B,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACrC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE;QAAE,MAAM,IAAI,UAAU,CAAC,KAAK,IAAI,gBAAgB,CAAC,CAAA;IAC3E,OAAO,CAAW,CAAA;AACpB,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,QAAQ,CAAC,IAAgB,EAAE,IAAY;IACrD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC1B,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,OAAO,CAAA;AACxD,CAAC;AAED,4FAA4F;AAC5F,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,IAAY,EAAE,EAAa,EAAE,IAA2B;IAClF,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,EAAE,CAAA;IACrB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,UAAU,EAAE,CAAC;YAC5B,EAAE,CAAC,GAAG,CAAC,OAAO,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;YACnC,EAAE,CAAC,GAAG,CAAC,aAAa,IAAI,sBAAsB,CAAC,CAAA;YAC/C,OAAO,CAAC,CAAA;QACV,CAAC;QACD,EAAE,CAAC,GAAG,CAAC,OAAO,IAAI,KAAM,CAAW,CAAC,OAAO,EAAE,CAAC,CAAA;QAC9C,OAAO,CAAC,CAAA;IACV,CAAC;AACH,CAAC"}
@@ -0,0 +1,39 @@
1
+ /** The order `pwpack.json` members are written in. Members not listed follow, in their original order. */
2
+ export declare const IDENTITY_KEY_ORDER: readonly ["id", "version", "formatVersion", "engines", "requires", "license", "app", "packs"];
3
+ export declare const IDENTITY_FILE = "pwpack.json";
4
+ export type IdentityJson = Record<string, unknown>;
5
+ export interface PackPin {
6
+ readonly id: string;
7
+ readonly version: string;
8
+ readonly hash: string;
9
+ }
10
+ /** A copy of `doc` with its members in {@link IDENTITY_KEY_ORDER}. */
11
+ export declare function orderIdentity(doc: IdentityJson): IdentityJson;
12
+ /** The JSON text of `pwpack.json`: ordered members, two-space indent, trailing newline. */
13
+ export declare function formatIdentity(doc: IdentityJson): string;
14
+ /** Two-space JSON with a trailing newline, the format of every file the commands write. */
15
+ export declare function formatJson(value: unknown): string;
16
+ export declare function readIdentityFile(root: string): Promise<IdentityJson>;
17
+ export declare function writeIdentityFile(root: string, doc: IdentityJson): Promise<void>;
18
+ /** `^<major>.0.0` for a semver version — the range a requirement on that build declares. */
19
+ export declare function caretRange(version: string): string;
20
+ /** Adds the pin, or replaces the pin with the same id. Order of the others is kept. */
21
+ export declare function upsertPin(doc: IdentityJson, pin: PackPin): void;
22
+ /** Adds `{ id, range }` to `requires`, or updates the entry (object or bare name) for that id. */
23
+ export declare function upsertRequirement(doc: IdentityJson, id: string, range: string): void;
24
+ /** Pins listed in a parsed `pwpack.json`. */
25
+ export declare function pinsOf(doc: {
26
+ readonly packs?: readonly PackPin[];
27
+ } | null): readonly PackPin[];
28
+ /**
29
+ * Finds `node_modules/<name>/package.json` the way Node resolves a bare
30
+ * import, walking up from `fromDir`. Returns null when it is not installed.
31
+ */
32
+ export declare function findPackageJson(name: string, fromDir: string): string | null;
33
+ /** The engine version this command line runs with: the contracts package's version. */
34
+ export declare function engineVersion(fromDir?: string): string;
35
+ /** `>=<major>.<minor> <<major+1>`: this engine's release and every later one before the next major. */
36
+ export declare function engineRange(version: string): string;
37
+ /** Text without a leading byte-order mark. */
38
+ export declare function stripBom(text: string): string;
39
+ //# sourceMappingURL=identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../../src/commands/lib/identity.ts"],"names":[],"mappings":"AASA,0GAA0G;AAC1G,eAAO,MAAM,kBAAkB,+FAAgG,CAAA;AAE/H,eAAO,MAAM,aAAa,gBAAgB,CAAA;AAE1C,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAElD,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,GAAG,EAAE,YAAY,GAAG,YAAY,CAK7D;AAED,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAExD;AAED,2FAA2F;AAC3F,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEjD;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAW1E;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtF;AAED,4FAA4F;AAC5F,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED,uFAAuF;AACvF,wBAAgB,SAAS,CAAC,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAO/D;AAED,kGAAkG;AAClG,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAOpF;AAED,6CAA6C;AAC7C,wBAAgB,MAAM,CAAC,GAAG,EAAE;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,OAAO,EAAE,CAE9F;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS5E;AAID,uFAAuF;AACvF,wBAAgB,aAAa,CAAC,OAAO,GAAE,MAAgD,GAAG,MAAM,CAM/F;AAED,uGAAuG;AACvG,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAInD;AAED,8CAA8C;AAC9C,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Reading and writing a project's `pwpack.json`: stable key order, pins and
3
+ * requirements, and the engine range a new project declares.
4
+ */
5
+ import { existsSync, readFileSync } from 'node:fs';
6
+ import { readFile, writeFile } from 'node:fs/promises';
7
+ import { dirname, join } from 'node:path';
8
+ import { fileURLToPath } from 'node:url';
9
+ /** The order `pwpack.json` members are written in. Members not listed follow, in their original order. */
10
+ export const IDENTITY_KEY_ORDER = ['id', 'version', 'formatVersion', 'engines', 'requires', 'license', 'app', 'packs'];
11
+ export const IDENTITY_FILE = 'pwpack.json';
12
+ /** A copy of `doc` with its members in {@link IDENTITY_KEY_ORDER}. */
13
+ export function orderIdentity(doc) {
14
+ const out = {};
15
+ for (const key of IDENTITY_KEY_ORDER)
16
+ if (doc[key] !== undefined)
17
+ out[key] = doc[key];
18
+ for (const [key, value] of Object.entries(doc))
19
+ if (!(key in out) && value !== undefined)
20
+ out[key] = value;
21
+ return out;
22
+ }
23
+ /** The JSON text of `pwpack.json`: ordered members, two-space indent, trailing newline. */
24
+ export function formatIdentity(doc) {
25
+ return `${JSON.stringify(orderIdentity(doc), null, 2)}\n`;
26
+ }
27
+ /** Two-space JSON with a trailing newline, the format of every file the commands write. */
28
+ export function formatJson(value) {
29
+ return `${JSON.stringify(value, null, 2)}\n`;
30
+ }
31
+ export async function readIdentityFile(root) {
32
+ const text = await readFile(join(root, IDENTITY_FILE), 'utf8').catch(() => null);
33
+ if (text === null)
34
+ throw new Error(`${join(root, IDENTITY_FILE)} not found; run this inside a pwpack folder or pass --dir`);
35
+ let value;
36
+ try {
37
+ value = JSON.parse(stripBom(text));
38
+ }
39
+ catch (e) {
40
+ throw new Error(`${IDENTITY_FILE} is not JSON: ${e.message}`);
41
+ }
42
+ if (value === null || typeof value !== 'object' || Array.isArray(value))
43
+ throw new Error(`${IDENTITY_FILE} is not a JSON object`);
44
+ return value;
45
+ }
46
+ export async function writeIdentityFile(root, doc) {
47
+ await writeFile(join(root, IDENTITY_FILE), formatIdentity(doc));
48
+ }
49
+ /** `^<major>.0.0` for a semver version — the range a requirement on that build declares. */
50
+ export function caretRange(version) {
51
+ const major = /^(\d+)\./.exec(version)?.[1];
52
+ if (major === undefined)
53
+ throw new Error(`"${version}" is not a semver version`);
54
+ return `^${major}.0.0`;
55
+ }
56
+ /** Adds the pin, or replaces the pin with the same id. Order of the others is kept. */
57
+ export function upsertPin(doc, pin) {
58
+ const pins = Array.isArray(doc.packs) ? [...doc.packs] : [];
59
+ const entry = { id: pin.id, version: pin.version, hash: pin.hash };
60
+ const at = pins.findIndex((p) => p !== null && typeof p === 'object' && p.id === pin.id);
61
+ if (at >= 0)
62
+ pins[at] = entry;
63
+ else
64
+ pins.push(entry);
65
+ doc.packs = pins;
66
+ }
67
+ /** Adds `{ id, range }` to `requires`, or updates the entry (object or bare name) for that id. */
68
+ export function upsertRequirement(doc, id, range) {
69
+ const list = Array.isArray(doc.requires) ? [...doc.requires] : [];
70
+ const at = list.findIndex((r) => r === id || (r !== null && typeof r === 'object' && r.id === id));
71
+ const entry = { id, range };
72
+ if (at >= 0)
73
+ list[at] = entry;
74
+ else
75
+ list.push(entry);
76
+ doc.requires = list;
77
+ }
78
+ /** Pins listed in a parsed `pwpack.json`. */
79
+ export function pinsOf(doc) {
80
+ return doc?.packs ?? [];
81
+ }
82
+ /**
83
+ * Finds `node_modules/<name>/package.json` the way Node resolves a bare
84
+ * import, walking up from `fromDir`. Returns null when it is not installed.
85
+ */
86
+ export function findPackageJson(name, fromDir) {
87
+ let dir = fromDir;
88
+ for (;;) {
89
+ const candidate = join(dir, 'node_modules', ...name.split('/'), 'package.json');
90
+ if (existsSync(candidate))
91
+ return candidate;
92
+ const parent = dirname(dir);
93
+ if (parent === dir)
94
+ return null;
95
+ dir = parent;
96
+ }
97
+ }
98
+ const CONTRACTS_PACKAGE = '@pwfabric/contracts';
99
+ /** The engine version this command line runs with: the contracts package's version. */
100
+ export function engineVersion(fromDir = dirname(fileURLToPath(import.meta.url))) {
101
+ const path = findPackageJson(CONTRACTS_PACKAGE, fromDir);
102
+ if (!path)
103
+ throw new Error(`cannot find ${CONTRACTS_PACKAGE}; reinstall pwf`);
104
+ const { version } = JSON.parse(readFileSync(path, 'utf8'));
105
+ if (typeof version !== 'string')
106
+ throw new Error(`${path} has no version`);
107
+ return version;
108
+ }
109
+ /** `>=<major>.<minor> <<major+1>`: this engine's release and every later one before the next major. */
110
+ export function engineRange(version) {
111
+ const m = /^(\d+)\.(\d+)\./.exec(version);
112
+ if (!m)
113
+ throw new Error(`engine version "${version}" is not semver`);
114
+ return `>=${m[1]}.${m[2]} <${Number(m[1]) + 1}`;
115
+ }
116
+ /** Text without a leading byte-order mark. */
117
+ export function stripBom(text) {
118
+ return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
119
+ }
120
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../src/commands/lib/identity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { type PackFolder } from '@pwfabric/pack';
2
+ /** The project-local working directory (pack cache, build output of other commands). */
3
+ export declare const PWF_DIR = ".pwf";
4
+ /** Installed pack builds, one folder per `<id>@<version>`. */
5
+ export declare const PACK_CACHE_DIR = ".pwf/packs";
6
+ /** The note `create` writes into `atoms/`. Pack content (documentation, `DOC_FILE`), so it travels with the pack. */
7
+ export declare const ATOMS_README = "atoms/README.md";
8
+ /** Names skipped at any depth when a project is read: the defaults plus the cache and VCS ignore file. */
9
+ export declare const PROJECT_IGNORED_NAMES: ReadonlySet<string>;
10
+ /**
11
+ * Reads a project folder into memory, without the cache. The author's tooling
12
+ * (`package.json`, `scripts/`, …) is still in it — validation reports on it;
13
+ * `packContent` is what is packed, installed and hashed.
14
+ */
15
+ export declare function readProject(dir: string): Promise<PackFolder>;
16
+ /**
17
+ * Opens a pack source: a folder (read like a project, so its own `.pwf/`
18
+ * cache never travels) or a `.pwpack` / `.tgz` archive.
19
+ */
20
+ export declare function readPackSource(path: string): Promise<PackFolder>;
21
+ /**
22
+ * Relative folder of one pack build in the cache: `.pwf/packs/<id>@<version>`.
23
+ * A scoped id (`@pwpack/acme/cards`) nests the way npm scopes do. Throws when
24
+ * the id or version could escape the cache.
25
+ */
26
+ export declare function cacheRelDir(id: string, version: string): string;
27
+ /** Absolute folder of one pack build in a project's cache. */
28
+ export declare function cacheDir(root: string, id: string, version: string): string;
29
+ /** Reads a cached pack build exactly as it was written: nothing is skipped. */
30
+ export declare function readCachedPack(dir: string): Promise<PackFolder>;
31
+ /** Writes a pack folder to disk, replacing whatever was there. */
32
+ export declare function writePackFolder(dir: string, pack: PackFolder): Promise<void>;
33
+ /** Resolves a user-given path against the command's working directory. */
34
+ export declare function resolveFrom(cwd: string, path: string | undefined): string;
35
+ //# sourceMappingURL=project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../../src/commands/lib/project.ts"],"names":[],"mappings":"AAYA,OAAO,EAKL,KAAK,UAAU,EAChB,MAAM,gBAAgB,CAAA;AAEvB,wFAAwF;AACxF,eAAO,MAAM,OAAO,SAAS,CAAA;AAC7B,8DAA8D;AAC9D,eAAO,MAAM,cAAc,eAAqB,CAAA;AAChD,qHAAqH;AACrH,eAAO,MAAM,YAAY,oBAAoB,CAAA;AAE7C,0GAA0G;AAC1G,eAAO,MAAM,qBAAqB,EAAE,WAAW,CAAC,MAAM,CAA8D,CAAA;AAEpH;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAKlE;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAKtE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAI/D;AAED,8DAA8D;AAC9D,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED,+EAA+E;AAC/E,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAErE;AAED,kEAAkE;AAClE,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAQlF;AAED,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAEzE"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * The project folder as the commands see it: which files belong to the pack,
3
+ * where the local pack cache lives, and how a pack source (folder or archive)
4
+ * is opened.
5
+ *
6
+ * A project is a pwpack folder plus things that are never packed: the `.pwf/`
7
+ * cache (installed pack builds), the `.gitignore` next to it, and anything
8
+ * else outside the pack content (`packContent`: `pwpack.json`, `LICENSE`,
9
+ * `NOTICE`, `README.md`, `app/`, `atoms/`, `media/`).
10
+ */
11
+ import { mkdir, readFile, rm, stat, writeFile } from 'node:fs/promises';
12
+ import { dirname, join, resolve } from 'node:path';
13
+ import { DEFAULT_IGNORED_NAMES, isSafePackPath, readFolder, readPwpack, } from '@pwfabric/pack';
14
+ /** The project-local working directory (pack cache, build output of other commands). */
15
+ export const PWF_DIR = '.pwf';
16
+ /** Installed pack builds, one folder per `<id>@<version>`. */
17
+ export const PACK_CACHE_DIR = `${PWF_DIR}/packs`;
18
+ /** The note `create` writes into `atoms/`. Pack content (documentation, `DOC_FILE`), so it travels with the pack. */
19
+ export const ATOMS_README = 'atoms/README.md';
20
+ /** Names skipped at any depth when a project is read: the defaults plus the cache and VCS ignore file. */
21
+ export const PROJECT_IGNORED_NAMES = new Set([...DEFAULT_IGNORED_NAMES, PWF_DIR, '.gitignore']);
22
+ /**
23
+ * Reads a project folder into memory, without the cache. The author's tooling
24
+ * (`package.json`, `scripts/`, …) is still in it — validation reports on it;
25
+ * `packContent` is what is packed, installed and hashed.
26
+ */
27
+ export async function readProject(dir) {
28
+ const read = await readFolder(dir, { ignore: PROJECT_IGNORED_NAMES });
29
+ // A dot entry at the root (`.editorconfig`, `.vscode/`, …) is never pack
30
+ // content; it is the author's environment and is not reported on.
31
+ return { files: new Map([...read.files].filter(([path]) => !path.startsWith('.'))) };
32
+ }
33
+ /**
34
+ * Opens a pack source: a folder (read like a project, so its own `.pwf/`
35
+ * cache never travels) or a `.pwpack` / `.tgz` archive.
36
+ */
37
+ export async function readPackSource(path) {
38
+ const st = await stat(path).catch(() => null);
39
+ if (!st)
40
+ throw new Error(`no such file or folder: ${path}`);
41
+ if (st.isDirectory())
42
+ return readProject(path);
43
+ return readPwpack(new Uint8Array(await readFile(path)));
44
+ }
45
+ /**
46
+ * Relative folder of one pack build in the cache: `.pwf/packs/<id>@<version>`.
47
+ * A scoped id (`@pwpack/acme/cards`) nests the way npm scopes do. Throws when
48
+ * the id or version could escape the cache.
49
+ */
50
+ export function cacheRelDir(id, version) {
51
+ const rel = `${id}@${version}`;
52
+ if (!isSafePackPath(rel) || /[<>:"|?*]/.test(rel))
53
+ throw new Error(`pack id "${id}" with version "${version}" is not usable as a cache folder name`);
54
+ return `${PACK_CACHE_DIR}/${rel}`;
55
+ }
56
+ /** Absolute folder of one pack build in a project's cache. */
57
+ export function cacheDir(root, id, version) {
58
+ return join(root, ...cacheRelDir(id, version).split('/'));
59
+ }
60
+ /** Reads a cached pack build exactly as it was written: nothing is skipped. */
61
+ export async function readCachedPack(dir) {
62
+ return readFolder(dir, { ignore: new Set() });
63
+ }
64
+ /** Writes a pack folder to disk, replacing whatever was there. */
65
+ export async function writePackFolder(dir, pack) {
66
+ await rm(dir, { recursive: true, force: true });
67
+ await mkdir(dir, { recursive: true });
68
+ for (const [path, bytes] of pack.files) {
69
+ const target = join(dir, ...path.split('/'));
70
+ await mkdir(dirname(target), { recursive: true });
71
+ await writeFile(target, bytes);
72
+ }
73
+ }
74
+ /** Resolves a user-given path against the command's working directory. */
75
+ export function resolveFrom(cwd, path) {
76
+ return resolve(cwd, path ?? '.');
77
+ }
78
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/commands/lib/project.ts"],"names":[],"mappings":"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"}