निष्पादन सिमेंटिक्स, बाधाएँ, सुरक्षा

यह पृष्ठ बताता है कि Script रनटाइम पर कैसे काम करता है (क्रम, ट्रांज़ैक्शन, एरर, लॉकिंग), सेव करते समय किन स्थैतिक बाधाओं के अधीन होता है, और इसका सुरक्षा मॉडल क्या है। सिंटैक्स के लिए Statement कैटलॉग और मान अभिव्यक्ति, और व्यावहारिक संयोजन के लिए कुकबुक देखें।

निष्पादन क्रम

  • statements ऊपर से नीचे क्रमिक रूप से निष्पादित होते हैं। Return पर पहुँचते ही उसी बिंदु पर समाप्त हो जाता है।
  • निष्पादन कॉल के अनुरोध को संभालने वाले पथ पर इनलाइन होता है। कॉल की प्रतिक्रिया ही निष्पादन का परिणाम है (प्रतिक्रिया का स्वरूप Script अवलोकन में अनुरोध और प्रतिक्रिया देखें), और एक निष्पादन को मिलने वाला समय नीचे समय बजट में दिया गया है।

निष्पादन सिमेंटिक्स

Guard (पूर्व शर्त)

कोई समर्पित guard Statement नहीं है। इसे If और then:[Return] से व्यक्त किया जाता है। शर्त के उल्लंघन पर परिणाम लौटाया जाता है और इसके बाद के Statement निष्पादित नहीं होते (guard रहित Script भी निश्चित रूप से संभव है)।

{ "type": "If", "condition": { "<": [ "{ /wallet/fields/balance/en-US }", "{ /payload/fields/cost }" ] },
  "then": [ { "type": "Return", "value": { "ok": false, "reason": "insufficient credit" }, "statusCode": 402 } ] }

ट्रांज़ैक्शन नहीं और best-effort क्षतिपूर्ति

Script ट्रांज़ैक्शन नहीं है। विफलता पर इंजन अब तक किए गए कार्यों की क्षतिपूर्ति (compensation) का प्रयास करता है और एरर का कारण लौटाता है, पर इसकी निम्नलिखित सीमाएँ हैं (डिज़ाइन के तहत स्वीकार्य)।

  • डिलीट को पूर्ववत करना एक नया sys.id बनाता है, जिससे इसे इंगित करने वाले संदर्भ टूट जाते हैं।
  • बाहरी प्रभाव (Http) अपरिवर्तनीय है (जो कॉल पहले ही जा चुकी है और उसका शुल्क वापस नहीं लिया जा सकता)।
  • क्षतिपूर्ति बिल्कुल भी न चलने के कारण अप्रतिपूरित अवस्था रह सकती है।

यदि वास्तविक परमाणुता (atomicity) चाहिए, तो उपयोगकर्ता Script से सीधे क्षतिपूर्ति करता है, या अपरिवर्तनीय कार्यों (जैसे बाहरी कॉल) को सबसे अंत में रखता है। "जिसमें शृंखलन तो हो जाता है पर रोलबैक नहीं होता, और फिर भी जो सुरक्षित दिखता है" ऐसा क्रम सबसे खतरनाक है।

आशावादी लॉकिंग

update/patch की टक्कर को ResourceUpdate और ResourcePatch के version से सीमित किया जाता है। version (मान अभिव्यक्ति, Int) देने पर लक्ष्य के वर्तमान sys.version से मेल खाने पर ही अद्यतन होता है, और मेल न खाने पर वर्ज़न टकराव एरर के साथ abort हो जाता है (Try/catch से स्थानीय रूप से संभाला जा सकता है)। इसे छोड़ देने पर बिना जाँच के last-write-wins होता है। आमतौर पर ResourceRead या ResourceFind से पहले पढ़कर उसका sys.version पास किया जाता है (कुकबुक में आशावादी लॉकिंग CAS देखें)।

origin के आधार पर लेखन

लेखन हमेशा origin (draft) में परिलक्षित होता है, और delivery (CDA/ACDA) पर दृश्यता publish से नियंत्रित होती है (ResourceCreate/ResourceUpdate/ResourcePatch का publish, या ResourcePublish/ResourceUnpublish)।

किसे विफलता माना जाता है

निष्पादन के दौरान कोई एक Statement विफल हो जाए, तो जब तक उस विफलता को संभालने वाला Try न हो, निष्पादन उसी जगह रुक जाता है। इस समय इंजन तब तक किए गए कार्यों को पूर्ववत करने का प्रयास करता है। पूर्ववत करने की सीमाएँ हैं, और उनका विवरण ट्रांज़ैक्शन नहीं और best-effort क्षतिपूर्ति में दिया गया है।

विफल हुआ Statement यदि Try के भीतर है, तो उस विफलता को catch में संभाला जा सकता है। catch के भीतर /error से विफलता का विवरण ({ message }) संदर्भित किया जाता है। विफलता किस Statement में हुई, यह इसमें शामिल नहीं होता।

निम्नलिखित स्थितियों को विफलता माना जाता है।

Return विफलता नहीं है। यह निष्पादन को सामान्य रूप से जल्दी समाप्त करता है, इसलिए catch पर नहीं जाता।

Http के विफल होने के दो तरीके

Http की विफलता इस आधार पर दो प्रकार की होती है कि उसे status प्रतिक्रिया के रूप में संभाला जाता है या नहीं। इसी अंतर से तय होता है कि retry और ignoreStatusCode लागू होते हैं या नहीं।

प्रकारstatus प्रतिक्रिया के रूप में संभाली जाने वाली स्थितितुरंत विफल होने वाली स्थिति
लागू स्थितियाँलक्ष्य API द्वारा 400 या उससे अधिक status लौटाया जाना, समय समाप्त होना (status 504), लक्ष्य API से कनेक्ट न हो पाना या प्रतिक्रिया न पढ़ पाना (status 502), प्रतिक्रिया body का 10MiB से अधिक होना (status 502)responseType "Json" होने पर सफल प्रतिक्रिया की body का JSON न होना, भेजी जाने वाली फ़ाइल का डाउनलोड सीमा से अधिक होना, फ़ाइल URL द्वारा 2xx के अलावा कोई status लौटाया जाना या फ़ाइल URL से कनेक्ट न हो पाना, part के मान का प्रारूप गलत होना
retryनिर्दिष्ट संख्या जितनी बार पुनः प्रयास करता हैपुनः प्रयास नहीं करता
ignoreStatusCode: trueइसे विफलता नहीं माना जाता और { status, body } को परिणाम के रूप में बाइंड किया जाता हैलागू नहीं होता और इसे विफलता माना जाता है
Try/catchcatch में संभाला जा सकता हैcatch में संभाला जा सकता है

फ़ाइल भेजने की प्रक्रिया में विफल होने की शर्तें फ़ाइल को body के रूप में भेजना में विस्तार से दी गई हैं।

सर्वर-साइड एग्रीगेशन केवल गिनती तक

गिनती ResourceCount सर्वर पर करता है। यह आइटम पढ़कर नहीं लाता, इसलिए इस पर संसाधित आइटम संख्या की ऊपरी सीमा लागू नहीं होती।

sum और group-by के लिए समर्पित कोई सर्वर कार्य नहीं है। ऐसे एग्रीगेशन के लिए ResourceForEach से पुनरावृत्ति करते हुए SetVar और JsonLogic से स्वयं गणना करनी पड़ती है, इसलिए वह संसाधित आइटम संख्या की ऊपरी सीमा से बँधी होती है (कई मिलियन रिकॉर्ड के एग्रीगेशन के लिए अनुपयुक्त)। केवल गिनती चाहिए, तो पुनरावृत्ति किए बिना ResourceCount का उपयोग करें।

प्रतीक्षा और विलंब नहीं

Script में Delay Statement नहीं है। Script एक बार निष्पादित होकर समाप्त हो जाता है, और बाहरी job के समाप्त होने तक भीतर प्रतीक्षा या पोलिंग नहीं करता।

स्थैतिक बाधाएँ (सेव करते समय जाँच)

नीचे दी गई बातें Script को सेव (बनाते/संशोधित करते) करते समय जाँची जाती हैं। उल्लंघन होने पर सेव अस्वीकार कर दिया जाता है (यह रनटाइम पर नहीं, बल्कि रचना के समय की विफलता है)। कौन-सा उल्लंघन किस कोड के साथ अस्वीकृत होता है, यह त्रुटियाँ में दिया गया है।

बाधामान
प्रति परिभाषा बाहरी कॉल की अधिकतम संख्या (Http, EmailSend)प्लान के अनुसार (मूल्य योजनाएं देखें)
ResourceForEach कुल संसाधित आइटम की अधिकतम संख्या (घोषित limit न होने पर इसी मान तक पुनरावृत्ति; मेल खाते आइटम शेष रहते हुए अटकने पर विफल)10,000
प्रति परिभाषा SetVar की अधिकतम संख्या (नेस्टिंग सहित)10
प्रति परिभाषा Cache की अधिकतम संख्या (नेस्टिंग सहित, कार्य से निरपेक्ष रूप से जोड़कर)5। इससे अधिक होने पर सेव अस्वीकृत
Loop, ResourceForEach block के भीतर का Cacheसेव अस्वीकृत
Cache.keyकेवल लिटरल, अधिकतम 128 अक्षर। मान अभिव्यक्ति होने पर सेव अस्वीकृत
Cache.ttl1 से 30 सेकंड के बीच, छोड़ने पर 5 सेकंड। इससे बाहर होने पर सेव अस्वीकृत
प्रति परिभाषा कुल Statement की अधिकतम संख्या (नेस्टिंग सहित)प्लान के अनुसार (मूल्य योजनाएं देखें)
Http.retry की ऊपरी सीमा2
एक Http के अनुरोध body field (body, urlBody, multipartBody)तीनों में से केवल एक। दो या अधिक लिखने पर सेव अस्वीकृत
Http.multipartBody में part की संख्या1 या अधिक। खाली होने पर सेव अस्वीकृत
multipartBody part का value, urlठीक एक। दोनों लिखने या दोनों खाली छोड़ने पर सेव अस्वीकृत
multipartBody part का fileNameकेवल उसी part में जिसमें url लिखा हो। url के बिना लिखने पर सेव अस्वीकृत
Regex.pattern की लंबाई128 अक्षर
प्रति परिभाषा secrets की अधिकतम संख्या20
secrets का key1 से 64 अक्षर, केवल अंग्रेज़ी अक्षर, अंक, _, -। एक ही key दो बार हो तो सेव अस्वीकृत
secrets का value1 से 4,096 अक्षर। इससे बाहर होने पर सेव अस्वीकृत
{ /secrets… } संदर्भठीक /secrets/<घोषित key>। ऐसा न होने पर सेव अस्वीकृत
ServiceUser को बनाने या हटाने वाला Statementसेव अस्वीकृत। पठन के तीन Statement और ResourceUpdate, ResourcePatch ही यह संसाधन लेते हैं
anonymousCallEnabled true हो, तो where का createdBy: ":self"सेव अस्वीकृत
Media इंजेस्ट निर्देश का transformations (फ़ाइल रूपांतरण)केवल array। element का type PdfWatermark और color #RRGGBB हो। text में लिखी गई पूरी string ({ /pointer } के path सहित) उपयोग किए जा सकने वाले अक्षरों से बनी एक पंक्ति हो। उल्लंघन होने पर सेव अस्वीकृत
PdfWatermark के लिटरल text की लंबाई1 से 64 अक्षर। इससे बाहर होने पर सेव अस्वीकृत। { /pointer } वाले text की जाँच सेव करते समय नहीं, बल्कि निष्पादन के समय resolve हुए मान से होती है

ऊपर की तालिका में दी गई निश्चित सीमाएँ प्लेटफ़ॉर्म द्वारा तय किए गए मान हैं, इसलिए वे प्लान से निरपेक्ष रूप से समान रहती हैं। इसके विपरीत, प्रति परिभाषा कुल Statement संख्या और बाहरी कॉल संख्या प्लान-आधारित सीमाएँ हैं। ये दोनों कोई वैधता त्रुटि नहीं, बल्कि प्लान सीमा हैं, इसलिए इन्हें पार करने पर सहेजना/संशोधन प्लान सीमा पार होने के कारण अस्वीकृत होता है (वही परिभाषा किसी उच्च प्लान में स्वीकार्य होती है) और अपग्रेड से खुल जाता है। प्लान-आधारित मान मूल्य योजनाएं में हैं।

Media फ़ाइल इंजेस्ट, Http, EmailSend जैसी बाहरी कॉल के विपरीत, प्रति परिभाषा बाहरी कॉल की सीमा में शामिल नहीं होती।

ResourceForEach child रखने वाला एक composite Statement है, इसलिए वह स्वयं बाहरी कॉल की संख्या में नहीं गिना जाता। onEach के भीतर के बाहरी कॉल Statement (Http, EmailSend) गिने जाते हैं (स्थैतिक रूप से 1 गिने जाते हैं पर पुनरावृत्ति में हर आइटम पर वास्तव में निष्पादित होते हैं)। onEach में बाहरी कॉल या Media फ़ाइल इंजेस्ट रखी जा सकती है, और यही Loop की body पर भी लागू होता है। पुनरावृत्ति वास्तव में कितने चक्कर लगाती है, यह इस गिनती में नहीं आता, बल्कि नीचे दिए समय बजट में गुणा के रूप में आता है।

मान की लंबाई की ऊपरी सीमा (रनटाइम)

हस्ताक्षर और टेक्स्ट प्रोसेसिंग वाले Statement, तथा Cache द्वारा संभाले जाने वाले मान के आकार की एक ऊपरी सीमा है। यह अभिव्यक्ति की लंबाई नहीं, बल्कि उस अभिव्यक्ति के resolve हुए मान की लंबाई है ({ /rawPayload } के सोलह अक्षर कई दसियों KB की ओर संकेत करते हैं), और इसीलिए इसकी जाँच सेव के समय नहीं, बल्कि निष्पादन के दौरान होती है।

लक्ष्यऊपरी सीमापार होने पर
Signature का value65,536 अक्षरवह Statement विफल (status 422)
Hash का value128 अक्षरवह Statement विफल (status 422)
Regex का value10,240 अक्षर (10KiB)वह Statement विफल (status 400)
Cache का value10,240 बाइट (10KiB)वह Statement विफल (status 422)
  • चारों अन्य रनटाइम विफलताओं जैसी ही हैं, इसलिए इन्हें Try/catch से स्थानीय रूप से संभाला जा सकता है।
  • Signature की ऊपरी सीमा वास्तविक प्रदाताओं द्वारा भेजी जाने वाली body के आकार के अनुरूप रखी गई है (भुगतान इवेंट कुछ KB के, और ऑर्डर webhook कई दसियों KB तक के होते हैं)। Hash कुछ field जोड़ने की जगह है, इसलिए वह बहुत संकरी है।
  • Regex.pattern के 128 अक्षर ऊपर स्थैतिक बाधाएँ में दी गई सेव-समय की जाँच हैं। यह लंबाई भगदड़ रोकने का उपाय नहीं है ((a+)+$ छह अक्षरों में भी खतरनाक है)। भगदड़ को रोकने वाले उपाय हैं pattern को केवल लिटरल के रूप में लिखने देने वाला नियम और नीचे दिया समय बजट; लंबाई जो वादा करती है वह केवल इतना है कि इंसान उसे पढ़कर समीक्षा कर सके।

समय बजट (रनटाइम)

एक निष्पादन के लिए अधिकतम 180 सेकंड की अनुमति है। वास्तव में अनुमत समय Script की परिभाषा (फ़ाइल भेजने की स्थिति में प्लान भी) के अनुसार तय होता है, और यह मूल 30 सेकंड में बाहरी कॉल द्वारा उपयोग किए जा सकने वाले समय को जोड़कर बनता है।

यह बजट पूरे निष्पादन पर लागू होता है। इससे अलग, Http का एक अनुरोध उस अनुरोध के timeoutMs के भीतर पूरा होना चाहिए।

मूल 30 सेकंड

संसाधन पढ़ने और लिखने या Media फ़ाइल प्राप्त करके संसाधित करने जैसे, बाहरी कॉल के अलावा सभी कार्य इसी 30 सेकंड के भीतर संसाधित होते हैं। जिस Script में कोई बाहरी कॉल नहीं है, उसे 30 सेकंड की अनुमति मिलती है।

Statement के अनुसार जुड़ने वाला समय

क्रम से रखे गए Statement का समय पूरा जोड़ा जाता है।

Statementजुड़ने वाला समय
HttptimeoutMs (निर्दिष्ट न करने पर 30 सेकंड)। फ़ाइल भेजने पर हर फ़ाइल के लिए डाउनलोड समय (नीचे की तालिका) जोड़ा जाता है, और retry निर्दिष्ट किया हो तो पूरे योग को प्रयासों की संख्या (1 + retry) से गुणा किया जाता है
EmailSendtimeoutMs (निर्दिष्ट न करने पर 10 सेकंड)। यह पुनः प्रयास नहीं करता, इसलिए केवल एक बार जोड़ा जाता है
Ifthen और else में से अधिक लंबे वाले का समय
Parallelbranches में से सबसे लंबे वाले का समय
Trybody, catch, finally के समय का कुल योग
Loopbody के समय को maxIterations (निर्दिष्ट न करने पर 10,000) से गुणा करने पर मिलने वाला मान
ResourceForEachonEach के समय को limit (निर्दिष्ट न करने पर 10,000) से गुणा करने पर मिलने वाला मान
अन्य Statement (जो किसी दूसरे Statement को नहीं रखते)नहीं जोड़ा जाता। ये मूल 30 सेकंड के भीतर संसाधित होते हैं

पुनरावृत्ति के भीतर कोई बाहरी कॉल न हो, तो पुनरावृत्तियों की संख्या से गुणा करने पर भी जुड़ने वाला समय 0 होता है। इसलिए ऐसी पुनरावृत्ति को मूल 30 सेकंड के भीतर पूरा होना चाहिए।

प्रति फ़ाइल डाउनलोड समय

Planडाउनलोड समय
Freeलगभग 5.2 सेकंड
Basicलगभग 10.5 सेकंड
Proलगभग 10.5 सेकंड
Enterpriseलगभग 107.4 सेकंड

यह मान प्लान की डाउनलोड सीमा जितने डेटा को 10,000,000 बाइट प्रति सेकंड की दर से प्राप्त करने में लगने वाला समय है।

गणना का उदाहरण

Pro प्लान में दो फ़ोटो भेजने वाले एक Http (timeoutMs 30 सेकंड, retry 1) को कॉल करने वाली Script की गणना इस प्रकार होती है।

  • Http: (30 सेकंड + 10.5 सेकंड × 2) × 2 = लगभग 102 सेकंड
  • पूरा निष्पादन: 30 सेकंड + 102 सेकंड = लगभग 132 सेकंड

132 सेकंड 180 सेकंड से कम है, इसलिए इस Script को 132 सेकंड की अनुमति मिलती है।

180 सेकंड से अधिक होने पर

गणना किया गया मान 180 सेकंड से अधिक हो, तब भी Script सेव होती है और निष्पादित होती है। हालाँकि निष्पादन 180 सेकंड पर पहुँचते ही उसी बिंदु पर रुक जाता है।

प्रति प्लान संख्या सीमा

Script की प्रति Organization संख्या प्लान के अनुसार सीमित होती है।

PlanScript की संख्या
Free10
Basic30
Pro100
Enterpriseअसीमित

इससे अलग, एक Script परिभाषा जितने Statement और बाहरी कॉल (Http, EmailSend) रख सकती है उनकी संख्या भी प्लान के अनुसार सीमित है। परिभाषा को सहेजते/संशोधित करते समय उस प्लान की सीमा पार होने पर अस्वीकृत हो जाता है, और ठोस मानों के लिए मूल्य योजनाएं देखें।

सीमा तक पहुँचने पर नए Script का निर्माण अस्वीकार कर दिया जाता है।

Http फ़ाइल डाउनलोड का आकार

Http जब अनुरोध body के रूप में भेजी जाने वाली फ़ाइल को URL से प्राप्त करता है (urlBody, multipartBody का url part), तब हर फ़ाइल URL से प्राप्त किया जा सकने वाला आकार प्लान के अनुसार सीमित होता है। उस Script का स्वामी Space जिस Organization से संबंधित है, उसी का प्लान लागू होता है।

Planप्रति फ़ाइल URL अधिकतम आकार
Free50MiB
Basic100MiB
Pro100MiB
Enterprise1GiB
  • सीमा हर URL पर अलग-अलग लागू होती है। url part कई हों, तो हर फ़ाइल इस सीमा के भीतर होनी चाहिए।
  • सीमा से बड़ी फ़ाइल भेजने का प्रयास करने पर वह Http विफल हो जाता है (Http के विफल होने के दो तरीके देखें)।
  • यह सीमा समय बजट में जुड़ने वाले डाउनलोड समय का आधार भी है।

सुरक्षा मॉडल

secrets

बाहरी API key, भुगतान प्रदाता (PG) की secret key, webhook हस्ताक्षर key, और पहले से गणना किए गए Basic … प्रमाणीकरण मान जैसे गुप्त मानों को Statement में सीधे नहीं लिखा जाता। उन्हें परिभाषा के secrets में घोषित किया जाता है, और Statement में { /secrets/<key> } से पढ़ा जाता है। सार्वजनिक रूप से उपलब्ध टेस्ट key भी इसी जगह रखी जाती है। ऐसा करने पर असली key पर बदलते समय Statement को जैसा है वैसा ही छोड़कर केवल secrets का मान बदलना होता है।

"secrets": [
  { "key": "LLM_API_KEY",            "value": "sk-...",    "description": "LLM कॉल के लिए API key" },
  { "key": "WEBHOOK_SIGNING_SECRET", "value": "whsec_...", "description": "" }
],
"statements": [
  { "type": "Http", "method": "POST", "url": "https://api.openai.com/v1/chat/completions",
    "headers": [ { "key": "Authorization", "value": "Bearer { /secrets/LLM_API_KEY }" } ],
    "body": { /* ... */ }, "name": "llm" }
]
फ़ील्डआवश्यकनियम
keyआवश्यक1 से 64 अक्षर, और केवल अंग्रेज़ी अक्षर, अंक, _, - का उपयोग होता है। एक Script के भीतर अद्वितीय होना चाहिए।
valueआवश्यक1 से 4,096 अक्षरों की string। यह स्थैतिक मान है और इसकी व्याख्या टेम्प्लेट के रूप में नहीं होती, इसलिए इसमें { /… } रखने पर भी वह अक्षरशः ज्यों-का-त्यों उपयोग होता है।
descriptionआवश्यकउपयोग का विवरण, 0 से 128 अक्षर। खाली string "" भी मान्य है।
  • संग्रहण: value को WEEGLOO एन्क्रिप्ट करके सुरक्षित रूप से संग्रहीत करता है। Statement { /secrets/<key> } से मूल मान पढ़ता है।
  • पठन: Script लौटाने वाली API प्रतिक्रियाओं (पठन, निर्माण, संशोधन) में value मूल मान के रूप में लौटाया जाता है। जो भूमिका उस Script को पढ़ सकती है उसे यह मान दिख जाता है, इसलिए पढ़ने की अनुमति सीमित रखें। सदस्य (ServiceUser) Script की परिभाषा नहीं पढ़ सकते (पठन और रचना केवल CMA पर होते हैं, और ACMA में Script API नहीं है)।
  • संशोधन: पूर्ण संशोधन (PUT) पूरी परिभाषा को बदल देता है। secrets को छोड़कर भेजने पर घोषित गुप्त मान मिट जाते हैं, और यदि कोई Statement अब भी उस मान को { /secrets/… } से संदर्भित कर रहा हो, तो सेव अस्वीकृत हो जाता है। इसलिए हर संशोधन में secrets को साथ भेजें। पठन प्रतिक्रिया का मान ज्यों-का-त्यों वापस भेजना पर्याप्त है।
  • निष्पादन के दौरान मान: पढ़े गए मान के साथ क्या करना है, यह Statement तय करता है। पढ़े गए मान को Return से लौटाने पर वह निष्पादन प्रतिक्रिया और ScriptLog में रह जाता है, और SetVar, Cache, Content में रखने पर उस जगह मूल मान के रूप में रह जाता है। गुप्त मान केवल उसी बाहरी API को भेजें जिसे उस मान की आवश्यकता है।
  • App Bundle: जब Script को App Bundle में पैक किया जाता है, तब secrets का value ****** से छिपा दिया जाता है, जबकि key और description ज्यों-के-त्यों शामिल होते हैं। उस App Bundle को इंस्टॉल करके बनी Script में गुप्त मान ****** अवस्था में होते हैं, इसलिए इंस्टॉल करने वाले पक्ष को असली मान डालना होता है, तभी उस मान को पढ़ने वाला Statement काम करता है। secrets के बाहर की जगहों (Http के हेडर, Signature का secret आदि) में लिखे मान छिपाए नहीं जाते और ज्यों-के-त्यों शामिल होते हैं।

एक Script में अधिकतम 20 secrets रखे जा सकते हैं। पॉइंटर के नियम मान अभिव्यक्ति में /secrets में दिए गए हैं।

निष्पादन पहचान और प्राधिकरण

  • निष्पादन पहचान: निष्पादन के दौरान सभी संसाधन कार्य उस उपयोगकर्ता की पहचान से किए जाते हैं जिसने /execute को कॉल किया। बनाए या संशोधित होने वाले संसाधन के createdBy/updatedBy कॉलर होते हैं, और createdBy: ":self" स्कोप भी कॉलर के आधार पर हल होता है। अपवाद अनाम कॉल है। /execute/anonymous से आए निष्पादन में कोई कॉलर नहीं होता, इसलिए ये दोनों बातें रचयिता के आधार पर हल होती हैं (अनाम कॉल)।
  • प्राधिकरण की सीमाएँ दो हैं, और रनटाइम पर हर Statement के लिए संसाधन अनुमति की पुनः जाँच नहीं होती।
    1. रचना के समय (सेव): Script को सेव करते समय जाँच होती है कि रचयिता के पास उन Statement द्वारा उपयोग किए जाने वाले संसाधन और एक्शन की अनुमति वास्तव में है या नहीं। एक भी न हो, तो सेव अस्वीकार हो जाता है। यानी, बिना अनुमति वाले कार्य वाला Script शुरू से ही सेव नहीं होता। संसाधन चुनने वाला Statement, चाहे वह leaf हो या block रखने वाला ResourceForEach, सभी इस जाँच से गुज़रते हैं। पहले सेव कर दी गई परिभाषा भी संशोधन के समय दोबारा जाँची जाती है, इसलिए अनुमति वापस ले लिए जाने के बाद उस परिभाषा को संशोधित करके सेव नहीं किया जा सकता।
      • सदस्य डायरेक्टरी (ServiceUser) की जाँच अनुमति map से नहीं, बल्कि सेटिंग अक्ष से होती है। पठन के तीन Statement तथा ResourceUpdate, ResourcePatch में resource: "ServiceUser" लिखने के लिए रचयिता की SpaceRole के settings में SETTING_SERVICE_LOGIN (या SETTING_ALL) होना आवश्यक है (SpaceRole का settings)। कारण यह है कि सदस्य डायरेक्टरी बाकी सभी रास्तों पर भी Space सेटिंग के अधीन आने वाला संसाधन है।
      • सदस्य को बनाने या हटाने वाला Statement किसी भी भूमिका से सेव नहीं होता। Script सदस्य को बना या हटा नहीं सकता, इसलिए यह अनुमति की कमी (403) नहीं, बल्कि गलत लिखे गए Statement (400) के रूप में अस्वीकृत होता है। अर्थात यह ऐसी रिक्तता नहीं है जिसे अनुमति जोड़कर बंद किया जा सके। अनुमत बदलाव केवल ResourceUpdate, ResourcePatch के roleOverride और enableLogin हैं (सदस्य डायरेक्टरी सँभालना)।
    2. कॉल के समय (/execute): केवल कॉलर की Script Execute अनुमति की जाँच होती है। अनुमति न हो, तो 403 मिलता है। पास होने पर हर Statement की संसाधन अनुमति रनटाइम पर दोबारा जाँचे बिना निष्पादित होती है। यह प्रोग्रामिंग में किसी फ़ंक्शन को निष्पादित करने की अनुमति जैसा ही तरीका है। फ़ंक्शन को निष्पादित करने की अनुमति भर होने पर, उसके भीतर के अलग-अलग कार्यों की अनुमति दोबारा नहीं पूछी जाती। अनाम कॉल के पथ पर यह जाँच नहीं होती। कारण यह है कि जाँचने के लिए कोई कॉलर ही नहीं होता, और इसीलिए उस पथ को खोलना एक Script को बिना प्रमाणीकरण सार्वजनिक कर देने के बराबर है।
  • सीधी कॉल पर रोक (directCallEnabled): यदि Script का directCallEnabled false है, तो /execute की सीधी कॉल स्वयं ही अस्वीकृत हो जाती है। यह गेट Execute अनुमति की जाँच पास कर लेने के बाद लगता है, इसलिए Execute अनुमति होने पर भी कॉल रुक जाती है। जिस कॉल करने वाले के पास अनुमति नहीं है, उसे इस गेट तक पहुँचने से पहले ही 403 मिल जाता है। यह गेट केवल उसी एंडपॉइंट पर है, इसलिए Webhook की लिंक्ड ऐक्शन (script) और Scheduler उसे पहले की तरह निष्पादित करते हैं। इसका डिफ़ॉल्ट मान true (सीधी कॉल की अनुमति) है।
  • अनाम कॉल (anonymousCallEnabled): इसका डिफ़ॉल्ट मान false है। true करने पर केवल वही Script बिना प्रमाणीकरण वाले समर्पित पथ (/execute/anonymous) से भी निष्पादित होती है, और तब निष्पादन पहचान कॉलर नहीं, बल्कि रचयिता होती है। ऊपर दी गई दोनों सीमाओं में से कॉल के समय की जाँच (Execute अनुमति) उस पथ पर नहीं होती, इसलिए वास्तविक प्रमाणीकरण Script स्वयं करती है (प्राप्त अनुरोध के हस्ताक्षर का सत्यापन)। इसे चालू करने की शर्तें और सेव के नियम अनाम कॉल में दिए गए हैं।
  • स्वामित्व स्कोप: where फ़िल्टर का createdBy: ":self" का अर्थ है "केवल वही जो वर्तमान कॉलर ने बनाया" (उदाहरण: केवल अपना वॉलेट देखना)। जिस Script में अनाम कॉल की अनुमति दी गई है, वहाँ इस फ़िल्टर का उपयोग नहीं किया जा सकता। कॉलर न होने के कारण यह रचयिता पर हल होता है, इसलिए स्वामित्व स्कोप का उसका मूल अर्थ ही नहीं बनता।
  • प्रत्यायोजित अनुमति (रचना में सावधानी): ऊपर की दोनों सीमाओं को मिलाने पर, Script का निष्पादन रचयिता की अनुमति प्रत्यायोजित रूप में पाकर किए जाने जैसा है। कॉलर के पास केवल Execute भर होना चाहिए, और Script के भीतर के Statement रचयिता को सेव के समय अधिकृत दायरे में ही निष्पादित होते हैं। इसलिए ऐसे संसाधन कार्य भी, जो कॉलर स्वयं नहीं कर सकता, Script के माध्यम से हो सकते हैं। रचयिता को दी गई अनुमति ही उस Script का प्रभाव-क्षेत्र है, इसलिए Script में शामिल किए जाने वाले कार्य सावधानी से तय किए जाते हैं।

सारांश चेकलिस्ट

सेव करने से पहले निम्नलिखित की पुष्टि करें।

  • अनाम कॉल (anonymousCallEnabled) चालू की हो, तो where में createdBy: ":self" नहीं है, और प्राप्त अनुरोध का सत्यापन करने वाला Statement (Signature आदि) सबसे आगे रखा है।
  • बाहरी कॉल (Http, EmailSend) और कुल Statement संख्या प्लान सीमा के भीतर हैं, तथा SetVar 10 या उससे कम और Cache 5 या उससे कम है।
  • Cache का उपयोग किया हो, तो key को लिटरल के रूप में लिखा है और उसे Loop या ResourceForEach के भीतर नहीं रखा है।
  • ResourceForEach से किसी बड़े समुच्चय पर पुनरावृत्ति करते हों, तो limit घोषित किया है या पूरा हो सकने योग्य आकार होने की पुष्टि की है।
  • पुनरावृत्ति (Loop, ResourceForEach) शामिल की हो, तो यह पुष्टि कर ली है कि वह पुनरावृत्ति गुणा के रूप में समय बजट में आती है (कोई बाहरी कॉल न हो, तो 30 सेकंड का मूल बजट ही सीमा है)।
  • बाहरी API key या हस्ताक्षर key जैसे गुप्त मान secrets में घोषित किए हैं और { /secrets/<key> } से पढ़े हैं। Statement में सीधे लिखा गया कोई गुप्त मान नहीं है।
  • पूर्ण संशोधन (PUT) से सेव करते हों, तो secrets को साथ भेजा है।
  • हस्ताक्षर सत्यापन में उपयोग होने वाला संदेश /payload से नहीं, बल्कि { /rawPayload } से लिया है।
  • सदस्य (ServiceUser) को सँभालने वाला Statement हो, तो रचयिता के पास SETTING_SERVICE_LOGIN है, और उस संसाधन को बनाने या हटाने वाला Statement नहीं डाला है।
  • अपरिवर्तनीय कार्य (बाहरी कॉल) यथासंभव बाद में रखे हैं।
  • Http से फ़ाइल भेजते हों, तो अनुरोध body field (body, urlBody, multipartBody) में से केवल एक लिखा है, और पुष्टि कर ली है कि हर फ़ाइल प्लान के अनुसार डाउनलोड सीमा के भीतर है।
  • update/patch की टक्कर की चिंता हो, तो ResourceUpdate या ResourcePatch के version का उपयोग करते हैं।
  • परिणाम लौटाना हो, तो Return.value निर्दिष्ट किया है।

त्रुटियाँ

ये कोड तब मिलते हैं जब परिभाषा का रूप स्थैतिक बाधाओं को तोड़ता है और सेव करना अस्वीकृत हो जाता है। मान अभिव्यक्ति के नियम तोड़ने वाले कोड मान अभिव्यक्ति की त्रुटियाँ में हैं, और कॉल करते या हटाते समय मिलने वाले कोड एंडपॉइंट की त्रुटियाँ में हैं। हर संसाधन में समान रूप से मिलने वाले कोड के लिए सामान्य त्रुटियाँ देखें।

कोडशर्त
WGL400066एक परिभाषा में रखे गए Cache Statement की संख्या 5 से अधिक है।
WGL400068Cache Statement को Loop या ResourceForEach के block के भीतर रखा गया है।
WGL400067Cache Statement के key में लिटरल के बजाय { /pointer } संदर्भ लिखा गया है।
WGL400065Cache Statement का ttl अनुमत सीमा से बाहर है।
WGL400063Cache Statement में उस action से असंबंधित field लिखा गया है (Get में ttl, Set में defaultValue)।
WGL400060ResourceCreate, ResourceDelete तथा प्रकाशन और संग्रहण के Statement के resource में "ServiceUser" लिखा गया है। सदस्य डायरेक्टरी केवल पठन के तीन Statement और ResourceUpdate, ResourcePatch लेती है।
WGL400077ResourceCount के resource में ऐसा संसाधन लिखा गया है जिसे गिना नहीं जा सकता। Media और सदस्य डायरेक्टरी (ServiceUser) गिने नहीं जा सकते।
WGL400037EmailSend में to और toServiceUser दोनों लिखे गए हैं या दोनों खाली हैं। ठीक एक ही लिखा जाता है।
WGL400054EmailSend के प्राप्तकर्ताओं की कुल संख्या (to 1 + cc + bcc) 50 से अधिक है।
WGL400039EmailSend का timeoutMs ऊपरी सीमा से अधिक है।
WGL400101EmailSend में body और templateBody दोनों लिखे गए हैं या दोनों खाली हैं। ठीक एक ही लिखा जाता है।
WGL400102EmailSend का templateBody.source इस Script के ResourceRead, ResourceFind से पढ़े गए Content को इंगित करने वाला एक pointer नहीं है। pointer के आगे-पीछे अन्य अक्षर होने पर भी यह अस्वीकृत हो जाता है।
WGL400061अनाम कॉल की अनुमति देने वाली Script (anonymousCallEnabled) में पठन Statement के where में createdBy: ":self" लिखा गया है।
WGL400023एक परिभाषा में रखे गए SetVar Statement की संख्या 10 से अधिक है।
WGL400026Http Statement का retry अपनी ऊपरी सीमा 2 से अधिक है।
WGL400087Http में अनुरोध body field (body, urlBody, multipartBody) में से दो या अधिक लिखे गए हैं।
WGL400088Http के multipartBody में एक भी part नहीं है।
WGL400089multipartBody के part में value और url दोनों लिखे गए हैं, या दोनों में से कोई भी नहीं लिखा गया है।
WGL400090multipartBody के part में url के बिना fileName लिखा गया है।
WGL400036ResourceForEach जितने आइटम संभाल सकता है, उसकी ऊपरी सीमा पार हो गई है।
WGL400094secrets में एक ही key का उपयोग करने वाले दो या अधिक आइटम हैं।
WGL400095एक परिभाषा में रखे गए secrets की संख्या 20 से अधिक है।
WGL400086secrets का value 1 से 4,096 अक्षरों की सीमा से बाहर है। त्रुटि में value शामिल नहीं होता।
WGL400086{ /pointer } के बिना लिखे गए PdfWatermark के text की लंबाई 1 से 64 अक्षरों की सीमा से बाहर है।
WGL400096Media इंजेस्ट निर्देश का transformations array नहीं है, या element का type PdfWatermark नहीं है, या PdfWatermark में text नहीं है अथवा वह ऑब्जेक्ट, array है, या color #RRGGBB प्रारूप में नहीं है, या लिखे गए रूप वाले text में उपयोग न किए जा सकने वाले अक्षर या line-break हैं।
WGL429005एक परिभाषा में रखे गए कुल Statement की संख्या प्लान की सीमा से अधिक है।
WGL429006एक परिभाषा में रखी गई बाहरी कॉल (Http, EmailSend) की संख्या प्लान की सीमा से अधिक है।
WGL403015परिभाषा में रखे गए Statement जिन संसाधनों और एक्शन का उपयोग करते हैं, उनकी अनुमति रचयिता के पास नहीं है। अनुमति होने पर भी, यदि उस अनुमति पर contentType, createdBy, tag फ़िल्टर लगा है तो सेव अस्वीकृत हो जाता है। अनुमति बिना शर्त वाली होनी चाहिए। इसका एकमात्र अपवाद Content Create है, जिसमें contentType का दायरा तय करने वाली अनुमति भी मान्य होती है और उसे Statement में लिखे contentType से मिलाकर देखा जाता है (Media Create में यह अपवाद नहीं है)। पठन Statement के resource में "ServiceUser" लिखा गया है पर रचयिता के पास SETTING_SERVICE_LOGIN नहीं है, यह स्थिति भी इसी कोड में आती है।