apptify 0.6.0 → 0.6.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apptify",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "An Apple-inspired, responsive Vue 3 component library.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -10,7 +10,7 @@
10
10
  "preview": "vite preview --host 127.0.0.1"
11
11
  },
12
12
  "dependencies": {
13
- "apptify": "^0.6.0",
13
+ "apptify": "^0.6.1",
14
14
  "vue": "^3.5.0",
15
15
  "vue-router": "^4.6.4",
16
16
  "vuetify": "^3.9.0",
@@ -1,6 +1,6 @@
1
1
  {
2
- "createdAt": "2026-10-04T14:04:37.104Z",
3
- "libraryVersion": "0.6.0",
2
+ "createdAt": "2026-10-04T16:10:51.852Z",
3
+ "libraryVersion": "0.6.1",
4
4
  "files": {
5
5
  "index.html": "75f6d93e3962ddca97a13b666a04d98ba9b263b6c288171383db764215034fea",
6
6
  "public/images/SOURCES.md": "24ccb6625b1168e48550b7651e9fc20cb747324d87666d39199608c7db20541b",
@@ -183,14 +183,15 @@
183
183
  "docs/PLAYGROUND-TEMPLATE.md": "e476d6622e89d8cb04d9acdd54c090e5d559d666bb49f266bcf36d3f3bf8fe67",
184
184
  "docs/VALIDATION.md": "3c1755f4699d6b7d8febb44b2b0b00eb416b86559c26d8b69e46a1c98271af5f",
185
185
  "README.md": "1e24796cf31d3d93f34e4edd32b8e1629b1dfdc175f74df573e14b4eb12186ed",
186
- "package.json": "677a70164d41c33517f36c661d773d17b4103d6e22fd55f8dc1df3c3bb3d2729",
186
+ "package.json": "780f0e2ce21421eb0b71c16ec19ab4d1276e94293e8be0ab1d7f1248296e999f",
187
187
  "index.html": "75f6d93e3962ddca97a13b666a04d98ba9b263b6c288171383db764215034fea",
188
188
  "vite.config.ts": "e2fee737d17c721cefaa33c955c6a7fcd47b46d51a95365768208eb16b608585",
189
189
  "vite.lib.config.ts": "f877c1772da70c9fed5174118ca36a0fc25fd46cce49b71280a5f91c4f8003a3",
190
190
  "tsconfig.json": "09590870bfbf6e90614d8a34af38b9a72902e8747ecd1a76be47ab24c842f9ea",
191
191
  "tsconfig.lib.json": "c885806b003cee01192cddcaf32df3e7c6d369e645360398aa088c14b1c4792f",
192
- "tooling/create-playground.mjs": "c45480c5982a64efd06f69dfb4620c65fd8ea35d01877b8574e7e2b30c095606",
192
+ "tooling/create-playground.mjs": "1252ef947ec8c1b3e0ca5d8c76cadacf69485aed5a181b866815cc9ed4658cc1",
193
+ "tooling/npm-command.mjs": "51c08c53cd395e32ec9b71b258dafadcdad3e6b227090d5b7bfbe55b9d0a97ba",
193
194
  "tooling/prepare-playground.mjs": "3a624b4966613a14e4f44a25555f25c564ea0fe69e5c68922c2ff5d21e1e2769",
194
- "tooling/prepare-package.mjs": "cf57a112eec798412e2a68089d1b2d25b984600d6ffef99397ec253abf2fca57"
195
+ "tooling/prepare-package.mjs": "a663ad0343bee2e711cdbc1c497daa89edc20752c67f17fc45d5173c6807b66b"
195
196
  }
196
197
  }
@@ -3,6 +3,7 @@ import { cp, mkdir, readFile, readdir, rename, writeFile } from 'node:fs/promise
3
3
  import { resolve, join, sep } from 'node:path'
4
4
  import { fileURLToPath } from 'node:url'
5
5
  import { execFileSync } from 'node:child_process'
6
+ import { npmCommand } from './npm-command.mjs'
6
7
 
7
8
  const root = fileURLToPath(new URL('../', import.meta.url))
8
9
  const destination = process.argv[2]
@@ -23,8 +24,8 @@ try {
23
24
  await rename(join(target, 'gitignore'), join(target, '.gitignore'))
24
25
  const vendor = join(target, 'vendor')
25
26
  await mkdir(vendor)
26
- const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm'
27
- const packed = JSON.parse(execFileSync(npm, ['pack', '--ignore-scripts', '--json', '--loglevel=error', '--pack-destination', vendor], { cwd: root, encoding: 'utf8' }))
27
+ const npm = npmCommand()
28
+ const packed = JSON.parse(execFileSync(npm.command, [...npm.args, 'pack', '--ignore-scripts', '--json', '--loglevel=error', '--pack-destination', vendor], { cwd: root, encoding: 'utf8' }))
28
29
  const manifest = JSON.parse(await readFile(join(target, 'package.json'), 'utf8'))
29
30
  manifest.dependencies.apptify = 'file:./vendor/' + packed[0].filename
30
31
  await writeFile(join(target, 'package.json'), JSON.stringify(manifest, null, 2) + '\n')
@@ -0,0 +1,16 @@
1
+ import { existsSync, realpathSync } from 'node:fs'
2
+ import { delimiter, dirname, join } from 'node:path'
3
+
4
+ // Run npm through Node so Windows .cmd shims never need shell quoting.
5
+ export function npmCommand(env = process.env) {
6
+ const candidates = [env.npm_execpath, join(dirname(process.execPath), 'node_modules/npm/bin/npm-cli.js')]
7
+ for (const directory of (env.PATH ?? env.Path ?? '').split(delimiter)) {
8
+ if (!directory) continue
9
+ candidates.push(join(directory, 'node_modules/npm/bin/npm-cli.js'))
10
+ const executable = join(directory, 'npm')
11
+ if (existsSync(executable)) candidates.push(realpathSync(executable))
12
+ }
13
+ const cli = candidates.find(path => path?.endsWith('npm-cli.js') && existsSync(path))
14
+ if (!cli) throw new Error('Cannot find npm-cli.js. Install npm alongside Node.js or set npm_execpath to its entry point.')
15
+ return { command: process.execPath, args: [cli] }
16
+ }
@@ -4,6 +4,7 @@ import { join, relative } from 'node:path'
4
4
  import { fileURLToPath } from 'node:url'
5
5
  import { createHash } from 'node:crypto'
6
6
  import { execFileSync } from 'node:child_process'
7
+ import { npmCommand } from './npm-command.mjs'
7
8
 
8
9
  const root = fileURLToPath(new URL('../', import.meta.url))
9
10
  async function sourceHashes() {
@@ -20,12 +21,12 @@ async function sourceHashes() {
20
21
  }
21
22
  }
22
23
  for (const name of ['src', 'playground', 'public', 'docs']) await directory(join(root, name))
23
- for (const name of ['README.md', 'package.json', 'index.html', 'vite.config.ts', 'vite.lib.config.ts', 'tsconfig.json', 'tsconfig.lib.json', 'tooling/create-playground.mjs', 'tooling/prepare-playground.mjs', 'tooling/prepare-package.mjs']) await record(join(root, name))
24
+ for (const name of ['README.md', 'package.json', 'index.html', 'vite.config.ts', 'vite.lib.config.ts', 'tsconfig.json', 'tsconfig.lib.json', 'tooling/create-playground.mjs', 'tooling/npm-command.mjs', 'tooling/prepare-playground.mjs', 'tooling/prepare-package.mjs']) await record(join(root, name))
24
25
  return files
25
26
  }
26
27
  const before = await sourceHashes()
27
- const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm'
28
- execFileSync(npm, ['run', 'build'], { cwd: root, stdio: 'inherit' })
28
+ const npm = npmCommand()
29
+ execFileSync(npm.command, [...npm.args, 'run', 'build'], { cwd: root, stdio: 'inherit' })
29
30
  execFileSync(process.execPath, [join(root, 'tooling/prepare-playground.mjs')], { cwd: root, stdio: 'inherit' })
30
31
  assert.deepEqual(await sourceHashes(), before, 'Sources changed during the build; rerun packing to take the latest snapshot. No source file was restored.')
31
32
  const snapshotPath = join(root, 'templates/playground/source-snapshot.json')
@@ -1,13 +1,14 @@
1
1
  import assert from 'node:assert/strict'
2
- import { mkdir, mkdtemp, readFile, readdir, rm, symlink, writeFile } from 'node:fs/promises'
2
+ import { chmod, mkdir, mkdtemp, readFile, readdir, rm, symlink, writeFile } from 'node:fs/promises'
3
3
  import { join } from 'node:path'
4
4
  import { tmpdir } from 'node:os'
5
5
  import { fileURLToPath } from 'node:url'
6
6
  import { execFileSync, spawnSync } from 'node:child_process'
7
+ import { npmCommand } from './npm-command.mjs'
7
8
 
8
9
  const root = fileURLToPath(new URL('../', import.meta.url))
9
10
  const scratch = await mkdtemp(join(tmpdir(), 'create-apptify-test-'))
10
- const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm'
11
+ const npm = npmCommand()
11
12
  const env = { ...process.env, npm_config_cache: join(scratch, 'cache'), npm_config_offline: 'true' }
12
13
  const installer = join(scratch, 'installer')
13
14
  const creator = join(installer, 'node_modules/create-apptify')
@@ -15,7 +16,7 @@ const library = join(installer, 'node_modules/apptify')
15
16
  const cli = join(creator, 'bin/create-apptify.mjs')
16
17
 
17
18
  async function unpack(cwd, destination) {
18
- const packed = JSON.parse(execFileSync(npm, ['pack', '--ignore-scripts', '--json', '--pack-destination', scratch], { cwd, env, encoding: 'utf8' }))[0]
19
+ const packed = JSON.parse(execFileSync(npm.command, [...npm.args, 'pack', '--ignore-scripts', '--json', '--pack-destination', scratch], { cwd, env, encoding: 'utf8' }))[0]
19
20
  await mkdir(destination, { recursive: true })
20
21
  execFileSync('tar', ['-xzf', join(scratch, packed.filename), '--strip-components=1', '-C', destination])
21
22
  return packed
@@ -27,9 +28,15 @@ try {
27
28
  const packed = await unpack(join(root, 'packages/create-apptify'), creator)
28
29
  const files = new Set(packed.files.map(file => file.path))
29
30
  for (const path of ['package.json', 'bin/create-apptify.mjs', 'README.md', 'LICENSE']) assert(files.has(path), 'Missing creator file: ' + path)
30
- await unpack(root, library)
31
+ const libraryPacked = await unpack(root, library)
32
+ assert(libraryPacked.files.some(file => file.path === 'tooling/npm-command.mjs'), 'Missing npm launcher in library tarball')
31
33
  await mkdir(join(installer, 'node_modules/.bin'))
32
- await symlink('../create-apptify/bin/create-apptify.mjs', join(installer, 'node_modules/.bin/create-apptify'))
34
+ if (process.platform === 'win32') {
35
+ await writeFile(join(installer, 'node_modules/.bin/create-apptify.cmd'), '@echo off\r\n"' + process.execPath + '" "%~dp0\\..\\create-apptify\\bin\\create-apptify.mjs" %*\r\n')
36
+ } else {
37
+ await chmod(cli, 0o755)
38
+ await symlink('../create-apptify/bin/create-apptify.mjs', join(installer, 'node_modules/.bin/create-apptify'))
39
+ }
33
40
  await writeFile(join(installer, 'package.json'), JSON.stringify({ private: true, dependencies: { 'create-apptify': packed.version } }) + '\n')
34
41
 
35
42
  const run = (args, cwd = installer) => spawnSync(process.execPath, [cli, ...args], { cwd, env, encoding: 'utf8' })
@@ -41,8 +48,8 @@ try {
41
48
  assert.equal(run(['--unknown']).status, 1)
42
49
  assert.equal(run(['one', 'two']).status, 1)
43
50
 
44
- const app = join(scratch, 'my app')
45
- const result = spawnSync(npm, ['create', 'apptify', '--offline', '--', app], { cwd: installer, env, encoding: 'utf8', timeout: 60_000 })
51
+ const app = join(scratch, 'my app & (demo)')
52
+ const result = spawnSync(npm.command, [...npm.args, 'create', 'apptify', '--offline', '--', app], { cwd: installer, env, encoding: 'utf8', timeout: 60_000 })
46
53
  assert.equal(result.status, 0, result.stdout + result.stderr)
47
54
  const manifest = JSON.parse(await readFile(join(app, 'package.json'), 'utf8'))
48
55
  assert.match(manifest.dependencies.apptify, /^file:\.\/vendor\/apptify-/)
@@ -62,7 +69,7 @@ try {
62
69
  assert.equal(await readFile(join(app, 'package.json'), 'utf8'), before)
63
70
  assert.equal(run([join(library, 'unsafe')]).status, 1)
64
71
  const alias = join(scratch, 'library-alias')
65
- await symlink(library, alias, 'dir')
72
+ await symlink(library, alias, process.platform === 'win32' ? 'junction' : 'dir')
66
73
  assert.equal(run([join(alias, 'unsafe')]).status, 1)
67
74
 
68
75
  const empty = join(scratch, 'existing-empty')
@@ -7,17 +7,18 @@ import { createHash } from 'node:crypto'
7
7
  import { execFileSync, spawn } from 'node:child_process'
8
8
  import { fileURLToPath } from 'node:url'
9
9
  import { chromium, expect } from '@playwright/test'
10
+ import { npmCommand } from './npm-command.mjs'
10
11
 
11
12
  const root = fileURLToPath(new URL('../', import.meta.url))
12
13
  const scratch = await mkdtemp(join(tmpdir(), 'apptify-package-'))
13
- const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm'
14
- const run = (args, cwd = root) => execFileSync(npm, args, { cwd, stdio: 'inherit', timeout: 240_000 })
14
+ const npm = npmCommand()
15
+ const run = (args, cwd = root) => execFileSync(npm.command, [...npm.args, ...args], { cwd, stdio: 'inherit', timeout: 240_000 })
15
16
  console.log('Package acceptance workspace: ' + scratch)
16
17
  const archiveInput = process.argv[2] ? resolve(process.argv[2]) : undefined
17
18
  const archiveSha256 = archiveInput ? createHash('sha256').update(await readFile(archiveInput)).digest('hex') : undefined
18
19
  const packArgs = ['pack', '--ignore-scripts', '--json', '--loglevel=error', '--pack-destination', scratch]
19
20
  if (archiveInput) packArgs.push(archiveInput)
20
- const packed = JSON.parse(execFileSync(npm, packArgs, { cwd: root, encoding: 'utf8' }))[0]
21
+ const packed = JSON.parse(execFileSync(npm.command, [...npm.args, ...packArgs], { cwd: root, encoding: 'utf8' }))[0]
21
22
  const contents = new Set(packed.files.map(file => file.path))
22
23
  const snapshot = archiveInput
23
24
  ? JSON.parse(execFileSync('tar', ['-xOf', join(scratch, packed.filename), 'package/templates/playground/source-snapshot.json'], { encoding: 'utf8' }))
@@ -78,7 +79,7 @@ async function serve() {
78
79
  })
79
80
  const port = reservation.address().port
80
81
  await new Promise((resolve, reject) => reservation.close(error => error ? reject(error) : resolve()))
81
- const child = spawn(npm, ['run', 'dev', '--', '--host', '127.0.0.1', '--port', String(port), '--strictPort'], { cwd: app, stdio: ['ignore', 'pipe', 'pipe'], detached: process.platform !== 'win32' })
82
+ const child = spawn(npm.command, [...npm.args, 'run', 'dev', '--', '--host', '127.0.0.1', '--port', String(port), '--strictPort'], { cwd: app, stdio: ['ignore', 'pipe', 'pipe'], detached: process.platform !== 'win32' })
82
83
  const stop = () => {
83
84
  if (process.platform !== 'win32') { try { process.kill(-child.pid, 'SIGTERM') } catch {} }
84
85
  else child.kill('SIGTERM')