Next.js website for Rocky Mountain Vending company featuring: - Product catalog with Stripe integration - Service areas and parts pages - Admin dashboard with Clerk authentication - SEO optimized pages with JSON-LD structured data Co-authored-by: Cursor <cursoragent@cursor.com>
168 lines
4.4 KiB
Text
Executable file
168 lines
4.4 KiB
Text
Executable file
'use strict';
|
|
|
|
const { assert } = require('@hapi/hoek');
|
|
|
|
const Any = require('./any');
|
|
const Common = require('../common');
|
|
const Compile = require('../compile');
|
|
const Errors = require('../errors');
|
|
|
|
|
|
const internals = {};
|
|
|
|
|
|
module.exports = Any.extend({
|
|
|
|
type: 'link',
|
|
|
|
properties: {
|
|
schemaChain: true
|
|
},
|
|
|
|
terms: {
|
|
|
|
link: { init: null, manifest: 'single', register: false }
|
|
},
|
|
|
|
args(schema, ref) {
|
|
|
|
return schema.ref(ref);
|
|
},
|
|
|
|
validate(value, { schema, state, prefs }) {
|
|
|
|
assert(schema.$_terms.link, 'Uninitialized link schema');
|
|
|
|
const linked = internals.generate(schema, value, state, prefs);
|
|
const ref = schema.$_terms.link[0].ref;
|
|
return linked.$_validate(value, state.nest(linked, `link:${ref.display}:${linked.type}`), prefs);
|
|
},
|
|
|
|
generate(schema, value, state, prefs) {
|
|
|
|
return internals.generate(schema, value, state, prefs);
|
|
},
|
|
|
|
rules: {
|
|
|
|
ref: {
|
|
method(ref) {
|
|
|
|
assert(!this.$_terms.link, 'Cannot reinitialize schema');
|
|
|
|
ref = Compile.ref(ref);
|
|
|
|
assert(ref.type === 'value' || ref.type === 'local', 'Invalid reference type:', ref.type);
|
|
assert(ref.type === 'local' || ref.ancestor === 'root' || ref.ancestor > 0, 'Link cannot reference itself');
|
|
|
|
const obj = this.clone();
|
|
obj.$_terms.link = [{ ref }];
|
|
return obj;
|
|
}
|
|
},
|
|
|
|
relative: {
|
|
method(enabled = true) {
|
|
|
|
return this.$_setFlag('relative', enabled);
|
|
}
|
|
}
|
|
},
|
|
|
|
overrides: {
|
|
|
|
concat(source) {
|
|
|
|
assert(this.$_terms.link, 'Uninitialized link schema');
|
|
assert(Common.isSchema(source), 'Invalid schema object');
|
|
assert(source.type !== 'link', 'Cannot merge type link with another link');
|
|
|
|
const obj = this.clone();
|
|
|
|
if (!obj.$_terms.whens) {
|
|
obj.$_terms.whens = [];
|
|
}
|
|
|
|
obj.$_terms.whens.push({ concat: source });
|
|
return obj.$_mutateRebuild();
|
|
}
|
|
},
|
|
|
|
manifest: {
|
|
|
|
build(obj, desc) {
|
|
|
|
assert(desc.link, 'Invalid link description missing link');
|
|
return obj.ref(desc.link);
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
// Helpers
|
|
|
|
internals.generate = function (schema, value, state, prefs) {
|
|
|
|
let linked = state.mainstay.links.get(schema);
|
|
if (linked) {
|
|
return linked._generate(value, state, prefs).schema;
|
|
}
|
|
|
|
const ref = schema.$_terms.link[0].ref;
|
|
const { perspective, path } = internals.perspective(ref, state);
|
|
internals.assert(perspective, 'which is outside of schema boundaries', ref, schema, state, prefs);
|
|
|
|
try {
|
|
linked = path.length ? perspective.$_reach(path) : perspective;
|
|
}
|
|
catch {
|
|
internals.assert(false, 'to non-existing schema', ref, schema, state, prefs);
|
|
}
|
|
|
|
internals.assert(linked.type !== 'link', 'which is another link', ref, schema, state, prefs);
|
|
|
|
if (!schema._flags.relative) {
|
|
state.mainstay.links.set(schema, linked);
|
|
}
|
|
|
|
return linked._generate(value, state, prefs).schema;
|
|
};
|
|
|
|
|
|
internals.perspective = function (ref, state) {
|
|
|
|
if (ref.type === 'local') {
|
|
for (const { schema, key } of state.schemas) { // From parent to root
|
|
const id = schema._flags.id || key;
|
|
if (id === ref.path[0]) {
|
|
return { perspective: schema, path: ref.path.slice(1) };
|
|
}
|
|
|
|
if (schema.$_terms.shared) {
|
|
for (const shared of schema.$_terms.shared) {
|
|
if (shared._flags.id === ref.path[0]) {
|
|
return { perspective: shared, path: ref.path.slice(1) };
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return { perspective: null, path: null };
|
|
}
|
|
|
|
if (ref.ancestor === 'root') {
|
|
return { perspective: state.schemas[state.schemas.length - 1].schema, path: ref.path };
|
|
}
|
|
|
|
return { perspective: state.schemas[ref.ancestor] && state.schemas[ref.ancestor].schema, path: ref.path };
|
|
};
|
|
|
|
|
|
internals.assert = function (condition, message, ref, schema, state, prefs) {
|
|
|
|
if (condition) { // Manual check to avoid generating error message on success
|
|
return;
|
|
}
|
|
|
|
assert(false, `"${Errors.label(schema._flags, state, prefs)}" contains link reference "${ref.display}" ${message}`);
|
|
};
|