@aex.is/zero 0.1.14 → 0.1.16

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.
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1,8 +1,8 @@
1
1
  export const modules = [
2
2
  {
3
3
  id: 'neon',
4
- label: 'Database (Neon)',
5
- description: 'Serverless Postgres with Neon.',
4
+ label: 'DB',
5
+ description: 'Serverless Postgres via Neon.',
6
6
  connect: {
7
7
  label: 'Connect to Neon',
8
8
  url: 'https://console.neon.tech/'
@@ -21,8 +21,8 @@ export const modules = [
21
21
  },
22
22
  {
23
23
  id: 'clerk',
24
- label: 'Auth (Clerk)',
25
- description: 'Authentication with Clerk.',
24
+ label: 'Auth',
25
+ description: 'Authentication via Clerk.',
26
26
  connect: {
27
27
  label: 'Connect to Clerk',
28
28
  url: 'https://dashboard.clerk.com'
@@ -46,8 +46,8 @@ export const modules = [
46
46
  },
47
47
  {
48
48
  id: 'payload',
49
- label: 'CMS (Payload)',
50
- description: 'Headless CMS using Payload.',
49
+ label: 'CMS',
50
+ description: 'Headless CMS via Payload.',
51
51
  connect: {
52
52
  label: 'Generate Payload Secret',
53
53
  url: 'https://payloadcms.com/docs'
@@ -71,8 +71,8 @@ export const modules = [
71
71
  },
72
72
  {
73
73
  id: 'stripe',
74
- label: 'Payments (Stripe)',
75
- description: 'Payments via Stripe SDK.',
74
+ label: 'Payments',
75
+ description: 'Payments via Stripe.',
76
76
  connect: {
77
77
  label: 'Connect to Stripe',
78
78
  url: 'https://dashboard.stripe.com/apikeys'
@@ -1,5 +1,5 @@
1
1
  import path from 'path';
2
- import { promises as fs } from 'fs';
2
+ import { constants as fsConstants, promises as fs } from 'fs';
3
3
  import { execa } from 'execa';
4
4
  import { getFrameworkDefinition } from '../config/frameworks.js';
5
5
  import { getBaseEnvHelp } from '../config/base-env.js';
@@ -65,6 +65,7 @@ async function ensureEmptyTargetDir(targetDir) {
65
65
  if (!stat.isDirectory()) {
66
66
  throw new Error('Target path exists and is not a directory.');
67
67
  }
68
+ await assertWritable(targetDir);
68
69
  const entries = await fs.readdir(targetDir);
69
70
  const allowed = new Set(['.git', '.gitignore', '.gitkeep']);
70
71
  const remaining = entries.filter((entry) => !allowed.has(entry));
@@ -74,11 +75,32 @@ async function ensureEmptyTargetDir(targetDir) {
74
75
  }
75
76
  catch (error) {
76
77
  if (isErrnoException(error) && error.code === 'ENOENT') {
77
- return;
78
+ try {
79
+ await fs.mkdir(targetDir, { recursive: true });
80
+ await assertWritable(targetDir);
81
+ return;
82
+ }
83
+ catch (createError) {
84
+ if (isErrnoException(createError) && (createError.code === 'EACCES' || createError.code === 'EPERM')) {
85
+ throw new Error('Cannot create target directory. Check your permissions and try again.');
86
+ }
87
+ throw createError;
88
+ }
89
+ }
90
+ if (isErrnoException(error) && (error.code === 'EACCES' || error.code === 'EPERM')) {
91
+ throw new Error('Target directory is not writable. Check your permissions and try again.');
78
92
  }
79
93
  throw error;
80
94
  }
81
95
  }
96
+ async function assertWritable(targetDir) {
97
+ try {
98
+ await fs.access(targetDir, fsConstants.W_OK);
99
+ }
100
+ catch {
101
+ throw new Error('Target directory is not writable. Check your permissions and try again.');
102
+ }
103
+ }
82
104
  async function runScaffoldCommand(runner, packageName, directoryInput, argSets) {
83
105
  const errors = [];
84
106
  const targetArg = directoryInput === '.' ? '.' : directoryInput;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aex.is/zero",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "description": "Aexis Zero scaffolding CLI",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",