instant-cli
Advanced tools
Comparing version 0.16.3 to 0.16.4
278
index.js
@@ -416,3 +416,3 @@ // @ts-check | ||
if (bag === "schema" || bag === "all") { | ||
const ok = await pushSchema(appId, opts); | ||
const { ok } = await pushSchema(appId, opts); | ||
if (!ok) return; | ||
@@ -491,3 +491,3 @@ } | ||
if (bag === "schema" || bag === "all") { | ||
const ok = await pullSchema(appId, pkgAndAuthInfo); | ||
const { ok } = await pullSchema(appId, pkgAndAuthInfo); | ||
if (!ok) return; | ||
@@ -735,3 +735,3 @@ } | ||
if (!pullRes.ok) return; | ||
if (!pullRes.ok) return pullRes; | ||
@@ -743,7 +743,6 @@ if ( | ||
console.log("Schema is empty. Skipping."); | ||
return; | ||
return { ok: true }; | ||
} | ||
const hasSchemaFile = await pathExists(join(pkgDir, "instant.schema.ts")); | ||
if (hasSchemaFile) { | ||
const prevSchema = await readLocalSchemaFile(); | ||
if (prevSchema) { | ||
const ok = await promptOk( | ||
@@ -753,3 +752,3 @@ "This will overwrite your local instant.schema file, OK to proceed?", | ||
if (!ok) return; | ||
if (!ok) return { ok: true }; | ||
} | ||
@@ -761,5 +760,4 @@ | ||
generateSchemaTypescriptFile( | ||
appId, | ||
prevSchema, | ||
pullRes.data.schema, | ||
pullRes.data["app-title"], | ||
instantModuleName, | ||
@@ -772,3 +770,3 @@ ), | ||
return true; | ||
return { ok: true }; | ||
} | ||
@@ -1006,5 +1004,5 @@ | ||
const schema = await readLocalSchemaFileWithErrorLogging(); | ||
if (!schema) return; | ||
if (!schema) return { ok: false }; | ||
console.log("Planning..."); | ||
console.log("Planning schema..."); | ||
@@ -1023,7 +1021,7 @@ const planRes = await fetchJson({ | ||
if (!planRes.ok) return; | ||
if (!planRes.ok) return planRes; | ||
if (!planRes.data.steps.length) { | ||
console.log("No schema changes detected. Exiting."); | ||
return; | ||
console.log("No schema changes detected. Skipping."); | ||
return { ok: true }; | ||
} | ||
@@ -1098,3 +1096,3 @@ | ||
const okPush = await promptOk("OK to proceed?"); | ||
if (!okPush) return; | ||
if (!okPush) return { ok: true }; | ||
@@ -1113,3 +1111,3 @@ const applyRes = await fetchJson({ | ||
if (!applyRes.ok) return; | ||
if (!applyRes.ok) return applyRes; | ||
@@ -1122,3 +1120,3 @@ if (applyRes.data["indexing-jobs"]) { | ||
return true; | ||
return { ok: true }; | ||
} | ||
@@ -1132,3 +1130,3 @@ | ||
console.log("Planning..."); | ||
console.log("Planning perms..."); | ||
@@ -1256,3 +1254,3 @@ const prodPerms = await fetchJson({ | ||
if (verbose && data) { | ||
console.log(debugName, "json:", JSON.stringify(data)); | ||
console.log(debugName, "json:", JSON.stringify(data, null, 2)); | ||
} | ||
@@ -1267,6 +1265,2 @@ if (!res.ok) { | ||
if (verbose) { | ||
console.log(debugName, "data:", data); | ||
} | ||
return { ok: true, data }; | ||
@@ -1304,3 +1298,3 @@ } catch (err) { | ||
if (options.y) return true; | ||
if (options.yes) return true; | ||
@@ -1483,3 +1477,3 @@ return await confirm({ | ||
function attrRevName(attr) { | ||
if (attr["reverse-entity"]) { | ||
if (attr["reverse-identity"]) { | ||
return `${attrRevEtype(attr)}.${attrRevLabel(attr)}`; | ||
@@ -1549,8 +1543,8 @@ } | ||
{ | ||
/** | ||
/** | ||
* Welcome to Instant's permission system! | ||
* Right now your rules are empty. To start filling them in, check out the docs: | ||
* https://www.instantdb.com/docs/permissions | ||
* | ||
* Here's an example to give you a feel: | ||
* | ||
* Here's an example to give you a feel: | ||
* posts: { | ||
@@ -1579,42 +1573,126 @@ * allow: { | ||
function generateSchemaTypescriptFile(id, schema, title, instantModuleName) { | ||
const entitiesEntriesCode = sortedEntries(schema.blobs) | ||
.map(([name, attrs]) => { | ||
// a block of code for each entity | ||
return [ | ||
` `, | ||
`"${name}"`, | ||
`: `, | ||
`i.entity`, | ||
`({`, | ||
`\n`, | ||
// a line of code for each attribute in the entity | ||
sortedEntries(attrs) | ||
.filter(([name]) => name !== "id") | ||
.map(([name, config]) => { | ||
const type = config["checked-data-type"] || "any"; | ||
function schemaBlobToCodeStr(name, attrs) { | ||
// a block of code for each entity | ||
return [ | ||
` `, | ||
`"${name}"`, | ||
`: `, | ||
`i.entity`, | ||
`({`, | ||
`\n`, | ||
// a line of code for each attribute in the entity | ||
sortedEntries(attrs) | ||
.filter(([name]) => name !== "id") | ||
.map(([name, config]) => { | ||
const type = config["checked-data-type"] || "any"; | ||
return [ | ||
` `, | ||
`"${name}"`, | ||
`: `, | ||
`i.${type}()`, | ||
config["unique?"] ? ".unique()" : "", | ||
config["index?"] ? ".indexed()" : "", | ||
`,`, | ||
].join(""); | ||
}) | ||
.join("\n"), | ||
`\n`, | ||
` `, | ||
`})`, | ||
`,`, | ||
].join(""); | ||
}) | ||
return [ | ||
` `, | ||
`"${name}"`, | ||
`: `, | ||
`i.${type}()`, | ||
config["unique?"] ? ".unique()" : "", | ||
config["index?"] ? ".indexed()" : "", | ||
`,`, | ||
].join(""); | ||
}) | ||
.join("\n"), | ||
`\n`, | ||
` `, | ||
`})`, | ||
`,`, | ||
].join(""); | ||
} | ||
/** | ||
* Note: | ||
* This is _very_ similar to `schemaBlobToCodeStr`. | ||
* | ||
* Right now, the frontend and backend have slightly different data structures for storing entity info. | ||
* | ||
* The backend returns {etype: attrs}, where attr keep things like `value-type` | ||
* The frontend stores {etype: EntityDef}, where EntityDef has a `valueType` field. | ||
* | ||
* For now, keeping the two functions separate. | ||
*/ | ||
function entityDefToCodeStr(name, edef) { | ||
// a block of code for each entity | ||
return [ | ||
` `, | ||
`"${name}"`, | ||
`: `, | ||
`i.entity`, | ||
`({`, | ||
`\n`, | ||
// a line of code for each attribute in the entity | ||
sortedEntries(edef.attrs) | ||
.map(([name, attr]) => { | ||
const type = attr["valueType"] || "any"; | ||
return [ | ||
` `, | ||
`"${name}"`, | ||
`: `, | ||
`i.${type}()`, | ||
attr?.config["unique"] ? ".unique()" : "", | ||
attr?.config["indexed"] ? ".indexed()" : "", | ||
`,`, | ||
].join(""); | ||
}) | ||
.join("\n"), | ||
`\n`, | ||
` `, | ||
`})`, | ||
`,`, | ||
].join(""); | ||
} | ||
function roomDefToCodeStr(room) { | ||
let ret = "{"; | ||
if (room.presence) { | ||
ret += `${entityDefToCodeStr("presence", room.presence)}`; | ||
} | ||
if (room.topics) { | ||
ret += `topics: {`; | ||
for (const [topicName, topicConfig] of Object.entries(room.topics)) { | ||
ret += entityDefToCodeStr(topicName, topicConfig); | ||
} | ||
ret += `}`; | ||
} | ||
ret += "}"; | ||
return ret; | ||
} | ||
function roomsCodeStr(rooms) { | ||
let ret = "{"; | ||
for (const [roomType, roomDef] of Object.entries(rooms)) { | ||
ret += `"${roomType}": ${roomDefToCodeStr(roomDef)},`; | ||
} | ||
ret += "}"; | ||
return ret; | ||
} | ||
function generateSchemaTypescriptFile( | ||
prevSchema, | ||
newSchema, | ||
instantModuleName, | ||
) { | ||
// entities | ||
const entitiesEntriesCode = sortedEntries(newSchema.blobs) | ||
.map(([name, attrs]) => schemaBlobToCodeStr(name, attrs)) | ||
.join("\n"); | ||
const entitiesObjCode = `{\n${entitiesEntriesCode}\n}`; | ||
const etypes = Object.keys(newSchema.blobs); | ||
const hasOnlyUserTable = etypes.length === 1 && etypes[0] === "$users"; | ||
const entitiesComment = hasOnlyUserTable | ||
? ` | ||
// This section lets you define entities: think \`posts\`, \`comments\`, etc | ||
// Take a look at the docs to learn more: | ||
// https://www.instantdb.com/docs/schema#defining-entities | ||
`.trim() | ||
: ""; | ||
const linksEntriesCode = Object.fromEntries( | ||
sortedEntries(schema.refs).map(([_name, config]) => { | ||
// links | ||
const linksEntries = Object.fromEntries( | ||
sortedEntries(newSchema.refs).map(([_name, config]) => { | ||
const [, fe, flabel] = config["forward-identity"]; | ||
@@ -1640,5 +1718,34 @@ const [, re, rlabel] = config["reverse-identity"]; | ||
); | ||
const linksEntriesCode = JSON.stringify(linksEntries, null, " ").trim(); | ||
const hasNoLinks = Object.keys(linksEntries).length === 0; | ||
const linksComment = hasNoLinks | ||
? ` | ||
// You can define links here. | ||
// For example, if \`posts\` should have many \`comments\`. | ||
// More in the docs: | ||
// https://www.instantdb.com/docs/schema#defining-links | ||
`.trim() | ||
: ""; | ||
// rooms | ||
const rooms = prevSchema?.rooms || {}; | ||
const roomsCode = roomsCodeStr(rooms); | ||
const roomsComment = | ||
Object.keys(rooms).length === 0 | ||
? ` | ||
// If you use presence, you can define a room schema here | ||
// https://www.instantdb.com/docs/schema#defining-rooms | ||
`.trim() | ||
: ""; | ||
const kv = (k, v, comment) => { | ||
return comment | ||
? ` | ||
${comment} | ||
${k}: ${v} | ||
`.trim() | ||
: `${k}: ${v}`; | ||
}; | ||
return ` | ||
// ${appDashUrl(id)} | ||
// Docs: https://www.instantdb.com/docs/schema | ||
@@ -1648,29 +1755,16 @@ | ||
const graph = i.graph( | ||
${ | ||
Object.keys(schema.blobs).length === 1 && | ||
Object.keys(schema.blobs)[0] === "$users" | ||
? ` | ||
// This section lets you define entities: think \`posts\`, \`comments\`, etc | ||
// Take a look at the docs to learn more: | ||
// https://www.instantdb.com/docs/schema#defining-entities | ||
`.trim() | ||
: "" | ||
} | ||
${indentLines(entitiesObjCode, 1)}, | ||
${ | ||
Object.keys(schema.refs).length === 0 | ||
? ` | ||
// You can define links here. | ||
// For example, if \`posts\` should have many \`comments\`. | ||
// More in the docs: | ||
// https://www.instantdb.com/docs/schema#defining-links | ||
`.trim() | ||
: "" | ||
} | ||
${indentLines(JSON.stringify(linksEntriesCode, null, " "), 1)} | ||
); | ||
const _schema = i.schema({ | ||
${kv("entities", entitiesObjCode, entitiesComment)}, | ||
${kv("links", linksEntriesCode, linksComment)}, | ||
${kv("rooms", roomsCode, roomsComment)} | ||
}); | ||
export default graph; | ||
// This helps Typescript display nicer intellisense | ||
type _AppSchema = typeof _schema; | ||
interface AppSchema extends _AppSchema {} | ||
const schema: AppSchema = _schema; | ||
export { type AppSchema } | ||
export default schema; | ||
`; | ||
} |
{ | ||
"name": "instant-cli", | ||
"type": "module", | ||
"version": "v0.16.3", | ||
"version": "v0.16.4", | ||
"description": "Instant's CLI", | ||
@@ -6,0 +6,0 @@ "scripts": { |
// Autogenerated by publish_packages.clj | ||
const version = "v0.16.3"; | ||
const version = "v0.16.4"; | ||
export default version; |
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
51749
1636