create-stator 1.4.0 → 1.5.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.
- package/index.js +51 -2
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -147,8 +147,18 @@ if (!template) {
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
// --- fetch ---
|
|
150
|
-
|
|
151
|
-
|
|
150
|
+
// Source and ref are held separately so provenance can record them apart:
|
|
151
|
+
// community sources may embed a ref (`github:user/repo/path#branch`), while
|
|
152
|
+
// first-party templates take it from --ref.
|
|
153
|
+
const sourceBase = (isRemoteSource(template) ? template : `${FIRST_PARTY}/${template}`).split(
|
|
154
|
+
'#',
|
|
155
|
+
)[0]
|
|
156
|
+
const refName = isRemoteSource(template)
|
|
157
|
+
? template.includes('#')
|
|
158
|
+
? template.slice(template.indexOf('#') + 1)
|
|
159
|
+
: null
|
|
160
|
+
: (flags.ref ?? null)
|
|
161
|
+
const source = refName ? `${sourceBase}#${refName}` : sourceBase
|
|
152
162
|
const s = p.spinner()
|
|
153
163
|
s.start(`Fetching ${template}`)
|
|
154
164
|
try {
|
|
@@ -175,6 +185,18 @@ try {
|
|
|
175
185
|
pkg.dependencies['@statorjs/stator'] = STATOR_RANGE
|
|
176
186
|
}
|
|
177
187
|
delete pkg.private
|
|
188
|
+
// Record where this scaffold came from. The commit is the merge base for a
|
|
189
|
+
// later template update (docs: recipes/updating-from-a-template) — the one
|
|
190
|
+
// fact that can only be captured now. Best-effort: null when offline.
|
|
191
|
+
pkg.stator = {
|
|
192
|
+
template: {
|
|
193
|
+
v: 1,
|
|
194
|
+
source: sourceBase,
|
|
195
|
+
ref: refName,
|
|
196
|
+
commit: resolveTemplateCommit(sourceBase, refName),
|
|
197
|
+
scaffoldedAt: new Date().toISOString(),
|
|
198
|
+
},
|
|
199
|
+
}
|
|
178
200
|
await writeFile(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`)
|
|
179
201
|
s.stop(`Scaffolded ${name} (${template})`)
|
|
180
202
|
} catch {
|
|
@@ -236,3 +258,30 @@ function bailIfCancelled(v) {
|
|
|
236
258
|
process.exit(0)
|
|
237
259
|
}
|
|
238
260
|
}
|
|
261
|
+
|
|
262
|
+
/** Resolve the template ref to a commit sha for provenance. Best-effort by
|
|
263
|
+
* design: no git, no network, or an unknown provider all return null rather
|
|
264
|
+
* than slow down or fail the scaffold. Annotated tags resolve to the peeled
|
|
265
|
+
* commit (`^{}`) when the host lists one. */
|
|
266
|
+
function resolveTemplateCommit(src, refName) {
|
|
267
|
+
if (refName && /^[0-9a-f]{40}$/.test(refName)) return refName
|
|
268
|
+
// giget providers that are also plain git hosts, for `git ls-remote`.
|
|
269
|
+
const hosts = {
|
|
270
|
+
gh: 'github.com',
|
|
271
|
+
github: 'github.com',
|
|
272
|
+
gitlab: 'gitlab.com',
|
|
273
|
+
bitbucket: 'bitbucket.org',
|
|
274
|
+
}
|
|
275
|
+
const m = src.match(/^([a-z]+):([^/]+\/[^/#]+)/)
|
|
276
|
+
const host = m && hosts[m[1]]
|
|
277
|
+
if (!host) return null
|
|
278
|
+
const out = spawnSync('git', ['ls-remote', `https://${host}/${m[2]}`, refName ?? 'HEAD'], {
|
|
279
|
+
encoding: 'utf8',
|
|
280
|
+
timeout: 15_000,
|
|
281
|
+
})
|
|
282
|
+
if (out.status !== 0 || !out.stdout) return null
|
|
283
|
+
const lines = out.stdout.trim().split('\n')
|
|
284
|
+
const line = lines.find((l) => l.includes('^{}')) ?? lines[0]
|
|
285
|
+
const sha = line?.split(/\s+/)[0]
|
|
286
|
+
return sha && /^[0-9a-f]{40}$/.test(sha) ? sha : null
|
|
287
|
+
}
|