@standards/client 0.0.0-stage → 1.0.0-alpha.382
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/LICENSE +111 -0
- package/README.md +61 -2
- package/dist/app.d.mts +67 -0
- package/dist/app.d.ts +67 -0
- package/dist/app.js +2 -0
- package/dist/app.mjs +2 -0
- package/dist/create-standards-3ODOXxRV.d.ts +439 -0
- package/dist/create-standards-Cl_Lxvy3.d.mts +439 -0
- package/dist/create-standards-DVK0prD0.js +2 -0
- package/dist/create-standards-p0dGJXSu.mjs +2 -0
- package/dist/http-transport-17TmxnFl.mjs +2 -0
- package/dist/http-transport-DBgedLFQ.d.mts +165 -0
- package/dist/http-transport-DBgedLFQ.d.ts +165 -0
- package/dist/http-transport-DHbErYa4.js +2 -0
- package/dist/index.d.mts +22 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +2 -0
- package/dist/index.mjs +2 -0
- package/dist/testing.d.mts +79 -0
- package/dist/testing.d.ts +79 -0
- package/dist/testing.js +2 -0
- package/dist/testing.mjs +2 -0
- package/package.json +81 -3
package/dist/testing.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! © 2025-2026 AND YOU CREATE SAS (RCS Paris 940 190 614). Proprietary — see LICENSE (Standards SDK License 1.0). */
|
|
2
|
+
import{g as e,m as t}from"./http-transport-17TmxnFl.mjs";import{a as n,o as r,s as i,t as a}from"./create-standards-p0dGJXSu.mjs";import{ValidationError as o,getSystemAttributeList as s,rejectUnknownAttributesOrThrow as c,validateQualifiedRule as l}from"@standards/schema";import{splitOperationInput as u}from"@standards/schema/api";var UnsupportedFilterOperatorError=class extends Error{constructor(e,t){super(`The in-memory test workspace does not serve the "${e}" operator (on "${t}"). Test it against a real workspace.`),this.name=`UnsupportedFilterOperatorError`,this.operator=e}};const d=new Set([`id`,`createdAt`,`updatedAt`]),f=new Set([`createdAt`,`updatedAt`]),p=new Set([`number`,`currency`]),m=new Set([`select`,`status`]),h=/^\d{4}-\d{2}-\d{2}/;function attributeValue(e,t){if(d.has(t))return e[t];let n=e.values[t];return typeof n==`object`&&n&&`value`in n&&!Array.isArray(n)?n.value:n}function isEmptyValue(e){return e==null||e===``||Array.isArray(e)&&e.length===0}function textOf(e){return e==null?null:e instanceof Date?e.toISOString():typeof e==`string`?e:JSON.stringify(e)}function members(e){return Array.isArray(e)?e.map(String):null}function dayOf(e){let t=textOf(e);if(t===null||!h.test(t))return null;let n=t.slice(0,10);return Number.isNaN(Date.parse(`${n}T00:00:00.000Z`))?null:n}function nextDay(e){let t=new Date(`${e}T00:00:00.000Z`);return t.setUTCDate(t.getUTCDate()+1),t.toISOString().slice(0,10)}function isUnmodelledDate(e){if(e?.type!==`date`)return!1;let t=e;return t.endDate===!0||t.includeTime===!0}function matchesDay(e,t,n,r){let i=dayOf(n);if(i===null)return!1;let a=textOf(t),o=nextDay(i),s=r?textOf(n)??i:i;switch(e){case`is`:return a!==null&&a>=s&&a<o;case`is_not`:return a===null||a<s||a>=o;case`greater_than`:return a!==null&&a>=o;case`greater_or_equal`:return a!==null&&a>=s;case`less_than`:return a!==null&&a<s;default:return a!==null&&a<o}}function compare(e,t,n){let r=textOf(e),i=textOf(t);if(r===null||i===null)return null;if(n){let e=Number(r),t=Number(i);return r===``||Number.isNaN(e)||Number.isNaN(t)?null:e-t}return r<i?-1:+(r>i)}function matchesRule(e,t,n){let r=n.attributes.find(e=>e.name===t.attribute)?.type,i=attributeValue(e,t.attribute),a=r!==void 0&&p.has(r),o=textOf(t.value)?.toLowerCase(),s=textOf(i)?.toLowerCase()??null;if((r===`date`||f.has(t.attribute))&&[`is`,`is_not`,`greater_than`,`greater_or_equal`,`less_than`,`less_or_equal`].includes(t.operator))return matchesDay(t.operator,i,t.value,f.has(t.attribute));switch(t.operator){case`is`:return r===`checkbox`||r===void 0&&typeof t.value==`boolean`?t.value===!0?i===!0:i!==!0:textOf(i)!==null&&textOf(i)===textOf(t.value);case`is_not`:return textOf(i)===null||textOf(i)!==textOf(t.value);case`contains`:return Array.isArray(i)?(Array.isArray(t.value)?t.value.map(String):[String(t.value)]).every(e=>i.map(String).includes(e)):s!==null&&o!==void 0&&s.includes(o);case`not_contains`:return i==null||!matchesRule(e,{...t,operator:`contains`},n);case`starts_with`:return s!==null&&o!==void 0&&s.startsWith(o);case`ends_with`:return s!==null&&o!==void 0&&s.endsWith(o);case`greater_than`:case`greater_or_equal`:case`less_than`:case`less_or_equal`:{let e=compare(i,t.value,a);return e===null?!1:t.operator===`greater_than`?e>0:t.operator===`greater_or_equal`?e>=0:t.operator===`less_than`?e<0:e<=0}case`is_empty`:return isEmptyValue(i);case`is_not_empty`:return!isEmptyValue(i);case`any_of`:{let e=members(t.value);return e===null||e.length===0||i==null?!1:Array.isArray(i)?i.some(t=>e.includes(String(t))):e.includes(textOf(i)??``)}case`none_of`:{let e=members(t.value);return e===null?!1:e.length===0||i==null?!0:Array.isArray(i)?!i.some(t=>e.includes(String(t))):!e.includes(textOf(i)??``)}default:throw new UnsupportedFilterOperatorError(t.operator,t.attribute)}}const g=new Set([`is`,`is_not`,`contains`,`not_contains`,`starts_with`,`ends_with`,`greater_than`,`greater_or_equal`,`less_than`,`less_or_equal`,`is_empty`,`is_not_empty`,`any_of`,`none_of`]);function assertServedOperators(e,t){for(let n of e?.rules??[])if(!g.has(n.operator)||isUnmodelledDate(t.attributes.find(e=>e.name===n.attribute))&&n.operator!==`is_empty`&&n.operator!==`is_not_empty`)throw new UnsupportedFilterOperatorError(n.operator,n.attribute)}function matchesFilters(e,t,n){let r=t?.rules??[];if(r.length===0)return!0;let i=r.map(t=>matchesRule(e,t,n));return t?.combinator===`or`?i.some(Boolean):i.every(Boolean)}function matchesSearch(e,t){let n=t.trim().toLowerCase();return n===``||Object.values(e.values).some(e=>(Array.isArray(e)?e:[e]).some(e=>typeof e==`string`&&e.toLowerCase().includes(n)))}function sortKey(e,t,n){let r=attributeValue(e,t),i=n.attributes.find(e=>e.name===t);return i&&m.has(i.type)?(i.options??[]).find(e=>e.value===r)?.label??r:r}function compareRecords(e,t){let n=e&&e.length>0?[...e]:[{attribute:`createdAt`,direction:`desc`}];return n.some(e=>e.attribute===`id`)||n.push({attribute:`id`,direction:`asc`}),(e,r)=>{for(let i of n){let n=t.attributes.find(e=>e.name===i.attribute)?.type,a=sortKey(e,i.attribute,t),o=sortKey(r,i.attribute,t),s=textOf(a)===null,c=textOf(o)===null;if(s||c){if(s&&c)continue;return s?1:-1}let l=compare(a,o,n!==void 0&&p.has(n))??0;if(l!==0)return i.direction===`desc`?-l:l}return 0}}const _=`SCHEMA_RECORD_NOT_FOUND`,v=`SCHEMA_VALIDATION_FAILED`,readNotFound=e=>`Record "${e}" not found.`,writeNotFound=e=>`Record with id "${e}" not found`,y=[`id`,`createdAt`,`updatedAt`];function withSystemAttributes(e){return{...e,attributes:[...e.attributes,...s()]}}function withoutSystemKeys(e){let t={...e};for(let e of y)delete t[e];return t}function boundOf(t,n,r){if(t==null)return r;if(typeof t!=`number`||!Number.isSafeInteger(t)||t<0)throw new e(400,`${n} must be a non-negative integer`);return t}function isObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function errorFor(n,r,i){return n===401||n===403?new t(n,r,i):new e(n,r,i)}function asTheServerValidates(t){try{t()}catch(t){throw t instanceof o?new e(400,t.message,t.code):t}}function notServed(t,n){return new e(501,`The in-memory test workspace does not serve ${t} ${n}: only the records API is in memory.`)}function isoOf(e,t){return e===void 0?t:e instanceof Date?e.toISOString():new Date(e).toISOString()}function wire(e){return JSON.parse(JSON.stringify(e))}function createInMemoryApi(t){let r=new Map;for(let e of t.schema.builders){let t=n(e);r.set(t.name,t)}let a=new Map([...r.keys()].map(e=>[e,[]])),o=new Set,s=null,d=0,f=1;function now(){return d=Math.max(Date.now(),d+1),new Date(d).toISOString()}function newId(){let e;do e=`00000000-0000-4000-8000-${(f++).toString(16).padStart(12,`0`)}`;while(o.has(e));return e}function objectOf(t){let n=r.get(t),i=a.get(t);if(!(n&&i))throw new e(404,`Object "${t}" not found. Make sure the object exists and you have access to it.`);return{definition:n,records:i}}function insert(e,t){let{records:n}=objectOf(e),{id:r,createdAt:a,updatedAt:s,...c}=t,l=now(),u={id:r??newId(),values:wire(i(c)),createdAt:isoOf(a,l),updatedAt:isoOf(s,isoOf(a,l)),visibility:`workspace`,ownedBy:null,metadata:{}};return n.push(u),o.add(u.id),u}function find(t,n){let r=objectOf(t).records.find(e=>e.id===n);if(!r)throw new e(404,readNotFound(n),_);return r}function requireWritable(t,n){if(!objectOf(t).records.some(e=>e.id===n))throw new e(404,writeNotFound(n),_)}function update(t,n,r){let i=objectOf(t).records.find(e=>e.id===n);if(!i)throw new e(404,writeNotFound(n),_);return Object.assign(i.values,withoutSystemKeys(r)),i.updatedAt=now(),i}function remove(t,n){let{records:r}=objectOf(t),i=r.findIndex(e=>e.id===n);if(i===-1)throw new e(404,writeNotFound(n),_);r.splice(i,1)}function list(e,t,n){let{definition:r,records:i}=objectOf(e);for(let e of t.filters?.rules??[])asTheServerValidates(()=>l(structuredClone(e),{attributes:r.attributes}));assertServedOperators(t.filters,r);let a=Math.min(boundOf(t.limit,`limit`,20),1e3),o=boundOf(t.offset,`offset`,0);if(a===0)return{data:[],page:{hasMore:!1,total:null,countMode:`none`}};let s=n?t.q:void 0,c=i.filter(e=>matchesFilters(e,t.filters,r)).filter(e=>s===void 0||matchesSearch(e,s)).sort(compareRecords(t.sorts,r)),u=c.slice(o,o+a);return{data:u,page:{hasMore:o+u.length<c.length,total:null,countMode:`none`}}}function bulk(t,n,r){let i=r.records??r.updates??r.ids;if(!Array.isArray(i)||i.length>100)throw new e(400,`A bulk request carries at most 100 items.`);let a=withSystemAttributes(objectOf(t).definition);if(n===`bulk-create`){let n=[],r=[];for(let[o,s]of i.entries()){if(!isObject(s)){r.push({index:o,error:`Record data must be an object`});continue}try{asTheServerValidates(()=>c(a,s)),n.push(insert(t,withoutSystemKeys(s)))}catch(t){if(!(t instanceof e))throw t;r.push({index:o,error:t.message})}}return{created:n,errors:r}}if(n===`bulk-update`){let n=[],r=[];for(let{id:o,data:s}of i)try{if(!isObject(s))throw new e(400,`Update data must be an object`,v);requireWritable(t,o),asTheServerValidates(()=>c(a,s)),n.push(update(t,o,s))}catch(t){if(!(t instanceof e))throw t;r.push({id:o,error:t.message,code:t.code??v})}return{updated:n,errors:r}}let o=[],s=[];for(let e of i)try{remove(t,e),o.push(e)}catch{s.push({id:e,error:writeNotFound(e),code:_})}return{deleted:o,errors:s}}function route(t,n,r){let[i,a,o,...s]=n.replace(/^\/+/,``).split(`/`);if(i!==`records`||a===void 0||s.length>0)throw notServed(t,n);let l=decodeURIComponent(a),u=o===void 0?void 0:decodeURIComponent(o),d=isObject(r)?r:{};if(t===`POST`&&u===void 0){let e=isObject(d.data)?d.data:{};return asTheServerValidates(()=>c(withSystemAttributes(objectOf(l).definition),e)),insert(l,withoutSystemKeys(e))}if(t===`POST`&&(u===`list`||u===`search`))return list(l,d,u===`search`);if(t===`POST`&&u?.startsWith(`bulk-`))return bulk(l,u,d);if(u===void 0)throw notServed(t,n);if(t===`GET`)return find(l,u);if(t===`PUT`||t===`PATCH`){if(Object.keys(d).length===0)throw new e(400,`Request body cannot be empty`);return requireWritable(l,u),asTheServerValidates(()=>c(withSystemAttributes(objectOf(l).definition),d)),update(l,u,d)}if(t===`DELETE`)return remove(l,u),null;throw notServed(t,n)}function request(e,t,n){return Promise.resolve().then(()=>(takeFailure(),wire(route(e,t,n===void 0?void 0:wire(n)))))}function takeFailure(){if(s){let{status:e,failure:t}=s;throw s=null,errorFor(e,t.message??`Request failed with status ${e}`,t.code)}}let p={call:(e,t)=>Promise.resolve().then(()=>{takeFailure();let{path:n}=u(e,t??{});throw notServed(e.method,n)}),get:e=>request(`GET`,e),post:(e,t)=>request(`POST`,e,t),patch:(e,t)=>request(`PATCH`,e,t),put:(e,t)=>request(`PUT`,e,t),delete:e=>request(`DELETE`,e),getText:e=>Promise.resolve().then(()=>{throw takeFailure(),notServed(`GET`,e)}),postRaw:e=>Promise.resolve().then(()=>{throw takeFailure(),notServed(`POST`,e)}),postMultipart:e=>Promise.resolve().then(()=>{throw takeFailure(),notServed(`POST`,e)})};return{transport:p,get:p.get,post:p.post,definitionOf:e=>objectOf(e).definition,seed:(e,t)=>t.map(t=>insert(e,t)),records:e=>objectOf(e).records,failNextRequestWith(e,t={}){s={status:e,failure:t}}}}function createTestStandards(e){let t=createInMemoryApi({schema:e.schema}),flatten=(e,n)=>r(t.definitionOf(e),JSON.parse(JSON.stringify(n)));return{db:a(t.transport,e.schema),seed:(e,n)=>t.seed(e,n).map(t=>flatten(e,t)),records:e=>t.records(e).map(t=>flatten(e,t)),failNextRequestWith:(e,n)=>t.failNextRequestWith(e,n)}}export{UnsupportedFilterOperatorError,createTestStandards};
|
package/package.json
CHANGED
|
@@ -1,6 +1,84 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@standards/client",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "1.0.0-alpha.382",
|
|
4
|
+
"description": "Public TypeScript client for Standards: declare schema sources with the fluent builders, sync them to a hosted tenant, and operate typed records over the REST API.",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/index.d.mts",
|
|
12
|
+
"default": "./dist/index.mjs"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"./testing": {
|
|
20
|
+
"import": {
|
|
21
|
+
"types": "./dist/testing.d.mts",
|
|
22
|
+
"default": "./dist/testing.mjs"
|
|
23
|
+
},
|
|
24
|
+
"require": {
|
|
25
|
+
"types": "./dist/testing.d.ts",
|
|
26
|
+
"default": "./dist/testing.js"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"./app": {
|
|
30
|
+
"import": {
|
|
31
|
+
"types": "./dist/app.d.mts",
|
|
32
|
+
"default": "./dist/app.mjs"
|
|
33
|
+
},
|
|
34
|
+
"require": {
|
|
35
|
+
"types": "./dist/app.d.ts",
|
|
36
|
+
"default": "./dist/app.js"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"sideEffects": false,
|
|
41
|
+
"files": [
|
|
42
|
+
"dist",
|
|
43
|
+
"LICENSE",
|
|
44
|
+
"README.md"
|
|
45
|
+
],
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=22"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@standards/schema": "1.0.0-alpha.382"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/node": "^25.6.0",
|
|
54
|
+
"jsdom": "^25.0.1",
|
|
55
|
+
"tsdown": "^0.23.0",
|
|
56
|
+
"typescript": "^5.6.3",
|
|
57
|
+
"typescript7": "npm:typescript@^7.0.2",
|
|
58
|
+
"vitest": "^5.0.0"
|
|
59
|
+
},
|
|
60
|
+
"publishConfig": {
|
|
61
|
+
"access": "public",
|
|
62
|
+
"registry": "https://registry.npmjs.org/"
|
|
63
|
+
},
|
|
64
|
+
"repository": {
|
|
65
|
+
"type": "git",
|
|
66
|
+
"url": "https://github.com/andyoucreate/standards.git",
|
|
67
|
+
"directory": "packages/client"
|
|
68
|
+
},
|
|
69
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
70
|
+
"author": "AndYouCreate",
|
|
71
|
+
"homepage": "https://docs.standards.new",
|
|
72
|
+
"standards": {
|
|
73
|
+
"entitlement": "core"
|
|
74
|
+
},
|
|
75
|
+
"scripts": {
|
|
76
|
+
"build": "tsdown",
|
|
77
|
+
"dev": "tsdown --watch",
|
|
78
|
+
"lint": "biome check .",
|
|
79
|
+
"test": "vitest run",
|
|
80
|
+
"typecheck": "node_modules/typescript7/bin/tsc --noEmit",
|
|
81
|
+
"typecheck:tests": "tsc --noEmit -p tsconfig.test.json",
|
|
82
|
+
"clean": "rm -rf dist"
|
|
83
|
+
}
|
|
6
84
|
}
|